{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import scipy as sp\n",
    "import matplotlib.pyplot as plt\n",
    "from ERANataf import ERANataf\n",
    "from ERADist import ERADist\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Problem description\n",
    "    ## Problem\n",
    "    ### Input: Capacity R~ Lognormal(mu_R=10,sigma_R=1.5),load S~Gumbel(mu_S = 5,sigma_S = 2)\n",
    "    ### Model limit state function g(R,S) = R -S \n",
    "    ### Quantity of interest: Q = Pr(g(R,S)<0\n",
    "    \n",
    "    ## Method\n",
    "    ### The Q_exact = 0.0331 (using the FORM can get the value analytically)\n",
    "    ### Try to use Monte Carlo Simulation( MCS ), Markov Chain Monte Carlo method(MCMC), the First Order Reliability method(FORM), the Important sampling method, the Cross-Entropy method(CE), the subset simulation (SuS) and the improved cross entropy method(iCE) to estimate the rare events probability and evaluate the quality of the esiimator and compare the method\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "## Parameter definition\n",
    "mu_R = 10; sigma_R= 1.5\n",
    "mu_S = 5; sigma_S = 2\n",
    "R_pdf = ERADist(\"Lognormal\",\"MOM\",[mu_R, sigma_R])\n",
    "S_pdf = ERADist(\"Gumbel\",\"MOM\",[mu_S,sigma_S])\n",
    "# target distribution\n",
    "f = lambda x: R_pdf.pdf(x[:,0])*S_pdf.pdf(x[:,1])\n",
    "# Performance function\n",
    "# g = lambda R,S: R-S\n",
    "g = lambda x: x[:,0]-x[:,1] # x has the size Nxdim\n",
    "# Threshold \n",
    "gamma = 0\n",
    "Q_exact = 0.0331\n",
    "dim = 2\n",
    "np.random.seed(1)# For reproducibility"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Crude Monte Carlo Simulation(MCS)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.03"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "## Monte Carlo Simulation \n",
    "N_MC = 1000\n",
    "# Sample generation\n",
    "x_MC = np.transpose([R_pdf.random(N_MC),S_pdf.random(N_MC)])\n",
    "# Performance function\n",
    "#g_MC = g(r_MC,s_MC)\n",
    "g_MC = g(x_MC)\n",
    "# Estimation of Q_MC \n",
    "Q_MC = sum(g_MC<=gamma)/N_MC\n",
    "# Evaluation of Q_MC coefficient of variation delta\n",
    "CV_MC = np.sqrt((1-Q_MC)/(Q_MC*N_MC))\n",
    "Q_MC"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1000, 2)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x_MC.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Markov Chain Monte Carlo method MCMC\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.0246"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "## Markov Chain Monte Carlo simulation using the random walk sampler Metropolis-Hastings algorithm (M-H algorithm)\n",
    "\n",
    "N_MCMC = 10000\n",
    "# Sample generation\n",
    "sp = [mu_R, mu_S]\n",
    "sigma = 2.4\n",
    "x = np.zeros((N_MCMC,2))\n",
    "x[0,:] = sp\n",
    "# generate z ~ N(0,sigma)\n",
    "Sigma = np.eye(2)*sigma;\n",
    "z = np.random.multivariate_normal([0,0],Sigma,N_MCMC)\n",
    "# Uniform sample\n",
    "u = np.random.uniform(0,1,N_MCMC)\n",
    "for i in range(N_MCMC-1):\n",
    "    # generate candidate\n",
    "    y = x[i,:] + z[i,:]\n",
    "    # evaluate the acceptance probability\n",
    "    f_y = R_pdf.pdf(y[0])*S_pdf.pdf(y[1])\n",
    "    f_x = R_pdf.pdf(x[i,0])*S_pdf.pdf(x[i,1])\n",
    "    alpha = min(1,f_y/f_x)\n",
    "    # check if sample should be accepted\n",
    "    if u[i] <= alpha:\n",
    "        x[i+1,:] = y\n",
    "    else:\n",
    "        x[i+1,:] = x[i,:]\n",
    "# The performance of the samples\n",
    "g_MCMC = x[:,0]-x[:,1]\n",
    "I_MCMC = g_MCMC < gamma\n",
    "Q_MCMC = sum(I_MCMC)/len(g_MCMC)\n",
    "Q_MCMC\n",
    "# nlags = 50\n",
    "#acf = np.correlate(I_MCMC,I_MCMC,mode='full')\n",
    "#delta = 2*sum(1)\n",
    "#CV_MCMC = np.var(I_MCMC)/N_MCMC*(1+delta)           \n",
    "## Comment MCMC needs more samples to reach the same level of accuracy as the MCS\n",
    "    \n",
    "    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## First order reliability method FORM\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.03314473756635762"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "## First Order reliability method (FORM) \n",
    "# First transform to the standard uniform space\n",
    "# Distribution object\n",
    "M = [ERADist(\"Lognormal\",\"MOM\",[mu_R, sigma_R]),ERADist(\"Gumbel\",\"MOM\",[mu_S,sigma_S])]\n",
    "Rho = np.identity(dim)\n",
    "# Apply the Nataf transformation\n",
    "T_Nataf = ERANataf(M,Rho)\n",
    "# N_FORM\n",
    "# Performance function in Physical space g = R-S\n",
    "g = lambda x: x[:,0]-x[:,1] # x: Nxdim\n",
    "#g = lambda x: x[1,:]-x[0,:]\n",
    "# Performance function in transformed space G = g\n",
    "# Gradient in physical space dg/dR=1 dg/dS=-1 dg = [] \n",
    "dg = lambda x: [1,-1]\n",
    "#dg = lambda x: [-1,1]\n",
    "# Gradient in transformed space dG = dg/det(Jac)\n",
    "# Design point in the transformed domain\n",
    "u0 = [0,0];\n",
    "# Maximum number of steps\n",
    "maxi = 100;\n",
    "u = np.zeros((dim,maxi))\n",
    "u[:,0]=u0\n",
    "for i in range(maxi):\n",
    "    [x_i,Jac] = T_Nataf.U2X(u[:,i].reshape(2,1),Jacobian=True)\n",
    "    g_i = g(np.transpose(x_i))\n",
    "    G_i = g_i\n",
    "    dg_i = dg(x_i)\n",
    "    dG_i = np.dot(dg_i,np.linalg.inv(Jac))\n",
    "    d_i = 1/np.power(np.linalg.norm(dG_i),2)*(np.dot(dG_i,u[:,i])-G_i)*np.transpose(dG_i)-u[:,i]\n",
    "    u[:,i+1] = u[:,i]+d_i\n",
    "    if np.linalg.norm(d_i)<1.e-5:\n",
    "        ustar = u[:,i]\n",
    "        break\n",
    "beta = np.linalg.norm(ustar)\n",
    "import scipy as sp\n",
    "Q_FORM = sp.stats.norm.cdf(-beta)\n",
    "-beta\n",
    "Q_FORM # analytical solution"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Importance sampling method\n",
    "    # IS density is predefined\n",
    "    # IS density based on the result of the FORM (the design point ustar in the transfromed space) h(u) = phi(u-ustar), mean is ustar Cov is identity matrix\n",
    "    # IS density is found by the Variance minimisation method\n",
    "    \n",
    "    # IS density is found by the CE method (analytical closed form is available for the exponential parametric family)\n",
    "        # IS density is found by IS-MCS\n",
    "        # IS denstiy is found by IS-IS\n",
    "            # Self version           \n",
    "            # Full version\n",
    "    # IS density is found by the improved CE method\n",
    "            \n",
    "          \n",
    "        "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Importance sampling method\n",
    "    # IS density is predefined"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.0002358016902179167"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "## Importance sampling method (Choose the IS density through the cross entropy method)\n",
    "# IS density using the cross entropy method\n",
    "# number of samples per level\n",
    "N_CE = 1000\n",
    "# Quantile value to select samples for parameter update\n",
    "p = 0.3\n",
    "# limit state function in physical space\n",
    "g = lambda x: x[:,0]-x[:,1] # x has the size Nxdim\n",
    "# distribution Nataf object or marginal distribution of the input variables in physical space\n",
    "M = [ERADist(\"Lognormal\",\"MOM\",[mu_R, sigma_R]),ERADist(\"Gumbel\",\"MOM\",[mu_S,sigma_S])]\n",
    "Rho = np.identity(dim)\n",
    "# Apply the Nataf transformation\n",
    "T_Nataf = ERANataf(M,Rho)\n",
    "dim = len(T_Nataf.Marginals)\n",
    "u2x = lambda u: T_Nataf.U2X(u)\n",
    "# Limist state function in standard space\n",
    "G_LSF = lambda u: g(u2x(u))\n",
    "# Initialization of variables and storage\n",
    "j = 0 # initial level\n",
    "maxT = 50 # estimated number of iterations\n",
    "N_tot = 0 # total number of samples\n",
    "mu_X = [mu_R, mu_S]\n",
    "Cov_X = [[np.power(sigma_R,2), 0], [0, np.power(sigma_S,2)]]\n",
    "for t in range(maxT):\n",
    "    # Generate samples from the current IS density\n",
    "    x_CE = sp.stats.multivariate_normal.rvs(mean=mu_X,cov = Cov_X,size=N_CE)\n",
    "    # Evaluate the responses\n",
    "    g_CE = g(x_CE)\n",
    "    # Sort the responses\n",
    "    g_CE_sort = np.sort(g_CE)\n",
    "    # Estimate gamma_t\n",
    "    gamma_t = max(g_CE_sort[int((1-p)*N_CE)],gamma)\n",
    "    # Solve the CE optimization problem using the MCS or IS method\n",
    "    # If we use MCS method we will not need additional weights\n",
    "\n",
    "    # update parameters\n",
    "    I_CE = g_CE< gamma_t\n",
    "    mu_X = sum((I_CE).reshape(1000,1)*x_CE)/sum(I_CE)\n",
    "    Xtmp = I_CE.reshape(1000,1)*x_CE-mu_X\n",
    "    Xo = (Xtmp)*np.transpose(np.tile(np.sqrt(I_CE),(dim,1)))\n",
    "    Cov_X = np.dot(np.transpose(Xo),Xo)/sum(I_CE)+1e-6*np.identity(dim)\n",
    "    \n",
    "    # If we use IS method we need additional weights  \n",
    "    \n",
    "    # Check if the final level is reached\n",
    "    if gamma_t == gamma:\n",
    "        break\n",
    "# Generate samples from the final distribution\n",
    "N_final = 1000\n",
    "x_CE = sp.stats.multivariate_normal.rvs(mean=mu_X,cov = Cov_X,size=N_final)\n",
    "# Evaluate the performance \n",
    "g_CE = g(x_CE)\n",
    "# Evaluate the weight\n",
    "f_CE = f(x_CE)\n",
    "h_CE = sp.stats.multivariate_normal.pdf(x_CE,mu_X,Cov_X)\n",
    "w_CE = f_CE/h_CE\n",
    "# Evaluate the Pr\n",
    "Q_CE1 = sum(I_CE*w_CE)/N_final\n",
    "# Quality of the estimator\n",
    "Var_CE1 = np.var(I_CE*w_CE)/N_final\n",
    "CV_CE1 = np.sqrt(Var_CE1)/Q_CE1\n",
    "Q_CE1\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Importance sampling method\n",
    "    # IS density based on the result of the FORM (the design point ustar in the transfromed space) h(u) = phi(u-ustar), mean is ustar Cov is identity matrix"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.00798079729701033"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "## Importance sampling method (Choose the IS density centered at the design point)\n",
    "N_IS = 1000\n",
    "# IS density\n",
    "# In the transformed space h(u) = multivariate normal distribution(u-ustar)\n",
    "mu_u = ustar\n",
    "Cov_u = np.identity(dim)\n",
    "#mu_u = [9,9]\n",
    "#Cov_u = 2*np.identity(dim)\n",
    "h = lambda u: sp.stats.multivariate_normal.pdf(u,mean=mu_u,cov = Cov_u)\n",
    "# Generate samples from IS density h\n",
    "u_IS =  sp.stats.multivariate_normal.rvs(mean=mu_u,cov = Cov_u,size=N_IS)\n",
    "x_IS =  T_Nataf.U2X(u_IS.reshape(2,1000)).reshape(N_IS,dim)\n",
    "w_IS = f(x_IS)/h(u_IS)\n",
    "# Evaluate the performance function\n",
    "g_IS = g(x_IS)\n",
    "# Estimate the Pr(P<0)\n",
    "I_IS = g_IS < gamma\n",
    "Q_IS = sum(I_IS*w_IS)/N_IS\n",
    "Q_IS"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Importance sampling method\n",
    "    # IS density is found by the Variance minimisation method"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "## Importance sampling method (Choose the IS density through the variance minimisation method)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Importance sampling method   \n",
    "    # IS density is found by the CE method (analytical closed form is available for the exponential parametric family)\n",
    "        # IS density is found by IS-MCS\n",
    "      \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.0002362279646701927"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "## Importance sampling method (Choose the IS density through the cross entropy method)\n",
    "# IS density using the cross entropy method\n",
    "# number of samples per level\n",
    "N_CE = 1000\n",
    "# Quantile value to select samples for parameter update\n",
    "p = 0.3\n",
    "# limit state function in physical space\n",
    "g = lambda x: x[:,0]-x[:,1] # x has the size Nxdim\n",
    "# distribution Nataf object or marginal distribution of the input variables in physical space\n",
    "M = [ERADist(\"Lognormal\",\"MOM\",[mu_R, sigma_R]),ERADist(\"Gumbel\",\"MOM\",[mu_S,sigma_S])]\n",
    "Rho = np.identity(dim)\n",
    "# Apply the Nataf transformation\n",
    "T_Nataf = ERANataf(M,Rho)\n",
    "dim = len(T_Nataf.Marginals)\n",
    "u2x = lambda u: T_Nataf.U2X(u)\n",
    "# Limist state function in standard space\n",
    "G_LSF = lambda u: g(u2x(u))\n",
    "# Initialization of variables and storage\n",
    "j = 0 # initial level\n",
    "maxT = 50 # estimated number of iterations\n",
    "N_tot = 0 # total number of samples\n",
    "mu_X = [mu_R, mu_S]\n",
    "Cov_X = [[np.power(sigma_R,2), 0], [0, np.power(sigma_S,2)]]\n",
    "for t in range(maxT):\n",
    "    # Generate samples from the current IS density\n",
    "    x_CE = sp.stats.multivariate_normal.rvs(mean=mu_X,cov = Cov_X,size=N_CE)\n",
    "    # Evaluate the responses\n",
    "    g_CE = g(x_CE)\n",
    "    # Sort the responses\n",
    "    g_CE_sort = np.sort(g_CE)\n",
    "    # Estimate gamma_t\n",
    "    gamma_t = max(g_CE_sort[int((1-p)*N_CE)],gamma)\n",
    "    # Solve the CE optimization problem using the MCS or IS method\n",
    "    # If we use MCS method we will not need additional weights\n",
    "\n",
    "    # update parameters\n",
    "    I_CE = g_CE< gamma_t\n",
    "    mu_X = sum((I_CE).reshape(1000,1)*x_CE)/sum(I_CE)\n",
    "    Xtmp = I_CE.reshape(1000,1)*x_CE-mu_X\n",
    "    Xo = (Xtmp)*np.transpose(np.tile(np.sqrt(I_CE),(dim,1)))\n",
    "    Cov_X = np.dot(np.transpose(Xo),Xo)/sum(I_CE)+1e-6*np.identity(dim)\n",
    "    \n",
    "    # If we use IS method we need additional weights  \n",
    "    \n",
    "    # Check if the final level is reached\n",
    "    if gamma_t == gamma:\n",
    "        break\n",
    "# Generate samples from the final distribution\n",
    "N_final = 1000\n",
    "x_CE = sp.stats.multivariate_normal.rvs(mean=mu_X,cov = Cov_X,size=N_final)\n",
    "# Evaluate the performance \n",
    "g_CE = g(x_CE)\n",
    "# Evaluate the weight\n",
    "f_CE = f(x_CE)\n",
    "h_CE = sp.stats.multivariate_normal.pdf(x_CE,mu_X,Cov_X)\n",
    "w_CE = f_CE/h_CE\n",
    "# Evaluate the Pr\n",
    "Q_CE1 = sum(I_CE*w_CE)/N_final\n",
    "# Quality of the estimator\n",
    "Var_CE1 = np.var(I_CE*w_CE)/N_final\n",
    "CV_CE1 = np.sqrt(Var_CE1)/Q_CE1\n",
    "Q_CE1\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Importance sampling method   \n",
    "    # IS density is found by the CE method (analytical closed form is available for the exponential parametric family)\n",
    "        # IS denstiy is found by IS-IS\n",
    "            # Self version\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.033745680792705283"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "## Importance sampling method (Choose the IS density through the cross entropy method)\n",
    "# IS density using the cross entropy method\n",
    "# number of samples per level\n",
    "N_CE = 1000\n",
    "# Quantile value to select samples for parameter update\n",
    "p = 0.3\n",
    "# limit state function in physical space\n",
    "g = lambda x: x[:,0]-x[:,1] # x has the size Nxdim\n",
    "# distribution Nataf object or marginal distribution of the input variables in physical space\n",
    "M = [ERADist(\"Lognormal\",\"MOM\",[mu_R, sigma_R]),ERADist(\"Gumbel\",\"MOM\",[mu_S,sigma_S])]\n",
    "Rho = np.identity(dim)\n",
    "# Apply the Nataf transformation\n",
    "T_Nataf = ERANataf(M,Rho)\n",
    "dim = len(T_Nataf.Marginals)\n",
    "u2x = lambda u: T_Nataf.U2X(u)\n",
    "# Limist state function in standard space\n",
    "G_LSF = lambda u: g(u2x(u))\n",
    "# Initialization of variables and storage\n",
    "j = 0 # initial level\n",
    "maxT = 50 # estimated number of iterations\n",
    "N_tot = 0 # total number of samples\n",
    "mu_X = [mu_R, mu_S]\n",
    "Cov_X = [[np.power(sigma_R,2), 0], [0, np.power(sigma_S,2)]]\n",
    "for t in range(maxT):\n",
    "    # Generate samples from the current IS density\n",
    "    x_CE = sp.stats.multivariate_normal.rvs(mean=mu_X,cov = Cov_X,size=N_CE)\n",
    "    # Evaluate the responses\n",
    "    g_CE = g(x_CE)\n",
    "    N_tot += N_CE\n",
    "    # Sort the responses\n",
    "    g_CE_sort = np.sort(g_CE)\n",
    "    # Estimate gamma_t\n",
    "    gamma_t = max(g_CE_sort[int(p*N_CE)],gamma)\n",
    "    # Solve the CE optimization problem using the MCS or IS method\n",
    "    # If we use MCS method we will not need additional weights\n",
    "    # If we use IS method we need additional weights w_IS_IS  \n",
    "\n",
    "    f_CE = f(x_CE)\n",
    "    h_CE = sp.stats.multivariate_normal.pdf(x_CE,mu_X,Cov_X)\n",
    "    w_IS_IS = f_CE/h_CE\n",
    "    # update parameters\n",
    "    I_CE = g_CE< gamma_t\n",
    "    mu_X = sum((I_CE*w_IS_IS).reshape(1000,1)*x_CE)/sum(I_CE*w_IS_IS)\n",
    "    Xtmp = I_CE.reshape(1000,1)*x_CE-mu_X\n",
    "    Xo = (Xtmp)*np.transpose(np.tile(np.sqrt(w_IS_IS*I_CE),(dim,1)))\n",
    "    Cov_X = np.dot(np.transpose(Xo),Xo)/sum(I_CE*w_IS_IS)+1e-6*np.identity(dim)    \n",
    "    # Check if the final level is reached\n",
    "    if gamma_t == gamma:\n",
    "        break\n",
    "N_final = 100\n",
    "# Generate samples from the final distribution\n",
    "x_CE = sp.stats.multivariate_normal.rvs(mean=mu_X,cov = Cov_X,size=N_final)\n",
    "# Evaluate the performance \n",
    "g_CE = g(x_CE)\n",
    "# Evaluate the weights\n",
    "f_CE = f(x_CE)\n",
    "h_CE = sp.stats.multivariate_normal.pdf(x_CE,mu_X,Cov_X)\n",
    "w_CE = f_CE/h_CE\n",
    "I_CE = g_CE < gamma\n",
    "# Evaluate the Pr\n",
    "Q_CE2 = sum(I_CE*w_CE)/N_final\n",
    "# Quality of the estimator\n",
    "Var_CE2 = np.var(I_CE*w_CE)/N_final\n",
    "CV_CE2 = np.sqrt(Var_CE2)/Q_CE2\n",
    "Q_CE2\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(100, 2)"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x_CE.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Importance sampling method   \n",
    "    # IS density is found by the CE method (analytical closed form is available for the exponential parametric family)\n",
    "        # IS denstiy is found by IS-IS\n",
    "            # Full version"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Intermediate failure threshold:  3.850472324051749\n",
      "\n",
      "Intermediate failure threshold:  1.2869763406287138\n",
      "\n",
      "Intermediate failure threshold:  0.0\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "0.035913389169843525"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "import scipy as sp\n",
    "from ERANataf import ERANataf\n",
    "from ERADist import ERADist\n",
    "## Parameter definition\n",
    "mu_R = 10; sigma_R= 1.5\n",
    "mu_S = 5; sigma_S = 2\n",
    "R_pdf = ERADist(\"Lognormal\",\"MOM\",[mu_R, sigma_R])\n",
    "S_pdf = ERADist(\"Gumbel\",\"MOM\",[mu_S,sigma_S])\n",
    "# target distribution\n",
    "f = lambda x: R_pdf.pdf(x[:,0])*S_pdf.pdf(x[:,1])\n",
    "# Performance function\n",
    "# g = lambda R,S: R-S\n",
    "g = lambda x: x[:,0]-x[:,1] # x has the size Nxdim\n",
    "# Threshold \n",
    "gamma = 0\n",
    "Q_exact = 0.0331\n",
    "dim = 2\n",
    "np.random.seed(1)# For reproducibility\n",
    "## Importance sampling method (Choose the IS density through the cross entropy method)\n",
    "# IS density using the cross entropy method\n",
    "# number of samples per level\n",
    "N_CE = 1000\n",
    "# Quantile value to select samples for parameter update\n",
    "p = 0.3\n",
    "# limit state function in physical space\n",
    "g = lambda x: x[:,0]-x[:,1] # x has the size Nxdim\n",
    "# distribution Nataf object or marginal distribution of the input variables in physical space\n",
    "M = [ERADist(\"Lognormal\",\"MOM\",[mu_R, sigma_R]),ERADist(\"Gumbel\",\"MOM\",[mu_S,sigma_S])]\n",
    "Rho = np.identity(dim)\n",
    "# Apply the Nataf transformation\n",
    "T_Nataf = ERANataf(M,Rho)\n",
    "dim = len(T_Nataf.Marginals)\n",
    "u2x = lambda u: T_Nataf.U2X(u)\n",
    "# Limist state function in standard space\n",
    "G_LSF = lambda u: g(u2x(u).T)\n",
    "# Initialization of variables and storage\n",
    "j = 0 # initial level\n",
    "maxT = 100 # estimated number of iterations\n",
    "N_tot = 0 # total number of samples\n",
    "# Definition of parameters of the random variables (uncorrelated standard normal)\n",
    "mu_init = np.zeros(dim)\n",
    "Si_init = np.eye(dim)\n",
    "gamma_hat = np.zeros((maxT + 1))\n",
    "samplesU = list()\n",
    "# CE procedure\n",
    "# Initial parameters\n",
    "gamma_hat[j]=1\n",
    "mu_hat = mu_init\n",
    "Si_hat = Si_init\n",
    "# Iteration\n",
    "for t in range(maxT):\n",
    "    # Generate samples and save them\n",
    "    U = sp.stats.multivariate_normal.rvs(mean = mu_hat,cov = Si_hat, size=N_CE).reshape(-1,dim)\n",
    "    samplesU.append(U.T)\n",
    "    # Count generated samples\n",
    "    N_tot +=N_CE\n",
    "    # Evaluate the limit state funtion\n",
    "    geval = G_LSF(U.T)\n",
    "    # Calculating h for the likelihood funtion\n",
    "    h = sp.stats.multivariate_normal.pdf(U,mu_hat,Si_hat)\n",
    "    # Check convergence\n",
    "    if gamma_hat[t] == 0:\n",
    "        break\n",
    "    # obtaining estimator gamma\n",
    "    gamma_hat[t+1] = np.maximum(0,np.nanpercentile(geval,p*100))\n",
    "    print(\"\\nIntermediate failure threshold: \",gamma_hat[t+1])\n",
    "    # Indicator function\n",
    "    I = geval <= gamma_hat[t+1]\n",
    "    # Likelihood ratio\n",
    "    W = (sp.stats.multivariate_normal.pdf(U,mean=np.zeros((dim)),cov = np.eye(dim))/h)\n",
    "    # Parameter update: Closed-form update\n",
    "    prod = np.matmul(W[I],U[I,:])\n",
    "    summ = np.sum(W[I])\n",
    "    mu_hat = (prod)/summ\n",
    "    Xtmp = U[I,:]-mu_hat\n",
    "    Xo = (Xtmp)*np.tile(np.sqrt(W[I]),(dim,1)).T\n",
    "    Si_hat = np.matmul(Xo.T,Xo)/np.sum(W[I])+1e-6*np.eye(dim)\n",
    "# needed steps\n",
    "T_CE = t\n",
    "#gamma_hat = gamma_hat[:,T_CE+1] # intermediate levels\n",
    "# Calculation of the probability of failure\n",
    "W_final = sp.stats.multivariate_normal.pdf(U,mean=np.zeros(dim),cov = np.eye(dim))/h\n",
    "I_final = geval <= 0\n",
    "Pr = 1/N_CE*sum(I_final*W_final)\n",
    "k_fin = 1 # final number of gaussinas in the mixture\n",
    "Pr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(4,)"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.zeros((4)).shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(4,)"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.zeros(4).shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "def CEIS_SG(N,p,g_fun,distr):\n",
    "    if isinstance(distr,ERANataf): #use Nataf transform (dependence)\n",
    "        dim = len(distr.Marginals) # number of random variables(dimension)\n",
    "        u2x = lambda u: distr.U2X(u) # from u to x\n",
    "    elif isinstance(distr[0],ERADist):# use distribution information for the transformation (independence)\n",
    "    # here we are assuming that all parameters have the same distribution \n",
    "    # Adjust accordingly otherwise\n",
    "        dim = len(distr)# number of random variables(dimenstion)\n",
    "        u2x = lambda u: distr[0].icdf(sp.stats.norm.cdf(u))# from u to x\n",
    "    else:\n",
    "        raise RuntimeError(\"Incorrect distribution. Please create an ERADist/ Nataf object!\")\n",
    "    # LSF in standard space\n",
    "    G_LSF = lambda u: g_fun(u2x(u))\n",
    "    # Initialization of variables and storage\n",
    "    t = 0 # initial level\n",
    "    maxT = 50 # estimated number of iterations\n",
    "    N_tot = 0 # total number of samples (total number of evaluations)\n",
    "    # Definition of parameters of the random variables in the transformed space(always uncorrelated)\n",
    "    mu_init = np.zeros(dim)\n",
    "    Si_init = np.identity(dim)\n",
    "    gamma_hat = np.zeros((maxT+1))\n",
    "    samplesU = list()\n",
    "    # CE procedure\n",
    "    # Initializing parameteres\n",
    "    gamma_hat[t] = 1\n",
    "    mu_U = mu_init\n",
    "    Si_U = Si_init\n",
    "    # Iteration\n",
    "    for t in range(maxT):\n",
    "        # Generate samples and save them\n",
    "        U = sp.stats.multivariate_normal.rvs(mean=mu_U,cov=Si_U,size=N).reshape(-1,dim) # U Nxdim\n",
    "        samplesU.append(U.T)\n",
    "        #Count generated samples\n",
    "        N_tot +=N\n",
    "        # Evaluation of the limit state function \n",
    "        geval = G_LSF(U.T)\n",
    "        # Calcultate h for the likelihood ratio\n",
    "        h = sp.stats.multivariate_normal.pdf(U,mu_U,Si_U)\n",
    "        # check convergence\n",
    "        if gamma_hat[t] == 0:\n",
    "            break\n",
    "        # obtaining estimator gamma\n",
    "        gamma_hat[t+1] = np.maximum(0,np.nanpercentile(geval,p*100))\n",
    "        print(\"\\nIntermediate failure threshold: \", gamma_hat[t+1])\n",
    "        # Indicator function\n",
    "        I = geval <= gamma_hat[t+1]\n",
    "        # Likelihood ratio\n",
    "        W  = sp.stats.multivariate_normal.pdf(U,mean=np.zeros(dim),cov=np.identity(dim))/h\n",
    "        # parameter updata: closed form update (IS estimation)\n",
    "        #prod = np.matmul(W[I],U[I,:])\n",
    "        prod = np.array((np.dot(W[I],U[I,0]),np.dot(W[I],U[I,1])))\n",
    "        summ = np.sum(W[I])\n",
    "        mu_U = prod / summ\n",
    "        Xtmp = U[I,:]-mu_U\n",
    "        Xo = (Xtmp)*np.tile(np.sqrt(W[I]),(dim,1)).T\n",
    "        Si_U = np.matmul(Xo.T,Xo) / np.sum(W[I]) + 1e-6*np.identity(dim)\n",
    "    # needed steps\n",
    "    lv = t+1\n",
    "    gamma_hat = gamma_hat[: lv+1]\n",
    "    # calculate the probability of failure\n",
    "    W_final= sp.stats.multivariate_normal.pdf(U,mean=np.zeros(dim),cov=np.identity(dim))/h\n",
    "    I_final = geval <= 0\n",
    "    Pr = 1/N* sum(I_final*W_final)\n",
    "    k_fin = 1\n",
    "    # transform the samples to the pyhsical/original space\n",
    "    samplesX = list()\n",
    "    for i in range(lv):\n",
    "        samplesX.append(u2x(samplesU[i][:,:]))\n",
    "    return Pr, lv, N_tot, gamma_hat, samplesU, samplesX, k_fin"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "CE-based IS stage: \n",
      "\n",
      "Intermediate failure threshold:  3.245902376965077\n",
      "\n",
      "Intermediate failure threshold:  0.2215812259650372\n",
      "\n",
      "Intermediate failure threshold:  0.0\n",
      "\n",
      "***Reference Pf:  0.0331  ***\n",
      "***CE-based IS Pf:  0.0339868938169038  ***\n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# CEIS_SG function call\n",
    "## Parameter definition\n",
    "mu_R = 10; sigma_R = 1.5\n",
    "mu_S = 5; sigma_S = 2\n",
    "R_pdf = ERADist('Lognormal','MOM',[mu_R, sigma_R])\n",
    "S_pdf = ERADist('Gumbel','MOM',[mu_S,sigma_S])\n",
    "# target distribution R,S are independent\n",
    "f = lambda x: R_pdf.pdf(x[:,0])*S_pdf.pdf(x[:,1])# x Nxdim\n",
    "# performance function g = R-S\n",
    "g = lambda x: x[0,:]-x[1,:]# X: N:dim\n",
    "# Threshold\n",
    "gamma = 0\n",
    "N_CE = 1000\n",
    "p = 0.2\n",
    "dim = 2\n",
    "# distribution Nataf object or marginal distribution of the input variables in physical space\n",
    "M = [R_pdf, S_pdf]\n",
    "Rho = np.identity(dim)\n",
    "# Apply the Nataf transformation\n",
    "T_Nataf = ERANataf(M,Rho)\n",
    "print(\"\\nCE-based IS stage: \")\n",
    "method = 'CE_SG'\n",
    "if method == 'CE_SG':\n",
    "    [Pr,lv,N_tot,gamma_hat,samplesU,samplesX,k_fin]=CEIS_SG(N_CE,p,g,T_Nataf)\n",
    "# reference solution\n",
    "Q_exact = 0.0331\n",
    "# show p_f results\n",
    "print(\"\\n***Reference Pf: \",Q_exact,\" ***\")\n",
    "print(\"***CE-based IS Pf: \",Pr,\" ***\\n\")\n",
    "# Plot samples\n",
    "if dim == 2:\n",
    "    nnp = 200\n",
    "    xx = np.linspace(-6,6,nnp)\n",
    "    [X,Y] = np.meshgrid(xx,xx)\n",
    "    xnod = np.array([X,Y])\n",
    "    Z = g(xnod)\n",
    "    fig,ax = plt.subplots(subplot_kw={\"aspect\": \"equal\"})\n",
    "    ax.contour(X,Y,Z,[0],colors='r',linewidths = 3)#LSF\n",
    "    for sample in samplesU:\n",
    "        ax.plot(*sample,\".\",markersize=2)\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Importance sampling method\n",
    "    # IS density is found by the improved CE method (iCE)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [],
   "source": [
    "def approx_normCDF(x):\n",
    "    # Return an approximation for the standard normal CDF based on a polynomial fit of degree 9\n",
    "    erfun = np.zeros(len(x))\n",
    "    idpos = x > 0\n",
    "    idneg = x < 0\n",
    "    t = (1+0.5*abs(x/np.sqrt(2)))**-1\n",
    "    tau = t*np.exp(\n",
    "        -((x/np.sqrt(2))**2)\n",
    "        -1.26551223\n",
    "        + 1.0000236 * t\n",
    "        + 0.37409196 * (t ** 2)\n",
    "        + 0.09678418 * (t ** 3)\n",
    "        - 0.18628806 * (t ** 4)\n",
    "        + 0.27886807 * (t ** 5)\n",
    "        - 1.13520398 * (t ** 6)\n",
    "        + 1.48851587 * (t ** 7)\n",
    "        - 0.82215223 * (t ** 8)\n",
    "        + 0.17087277 * (t ** 9)\n",
    "    )\n",
    "    erfun[idpos] = 1-tau[idpos]\n",
    "    erfun[idneg] = tau[idneg] -1\n",
    "    p = 0.5*(1+erfun)\n",
    "    return p"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "CE-based IS stage: \n"
     ]
    }
   ],
   "source": [
    "## Improved Cross Entropy method self written\n",
    "## Parameter definition\n",
    "mu_R = 10; sigma_R= 1.5\n",
    "mu_S = 5; sigma_S = 2\n",
    "R_pdf = ERADist(\"Lognormal\",\"MOM\",[mu_R, sigma_R])\n",
    "S_pdf = ERADist(\"Gumbel\",\"MOM\",[mu_S,sigma_S])\n",
    "# target distribution\n",
    "f = lambda x: R_pdf.pdf(x[:,0])*S_pdf.pdf(x[:,1])\n",
    "# Performance function\n",
    "# g = lambda R,S: R-S\n",
    "g = lambda x: x[0,:]-x[1,:] # x has the size dimxN\n",
    "# Threshold \n",
    "gamma = 0\n",
    "N_iCE = 1000\n",
    "p = 0.2\n",
    "dim = 2\n",
    "max_it = 50\n",
    "CV_target = 1.5\n",
    "# distribution Nataf object or marginal distribution of the input variables in physical space\n",
    "M = [R_pdf,S_pdf]\n",
    "Rho = np.identity(dim)\n",
    "# Apply the Nataf transformation\n",
    "T_Nataf = ERANataf(M,Rho)\n",
    "print(\"\\nCE-based IS stage: \")\n",
    "#dim = len(T_Nataf)\n",
    "u2x = lambda u: T_Nataf.U2X(u)\n",
    "# LSF in standard space\n",
    "G_LSF = lambda u: g(u2x(u))\n",
    "# Initialization of variables and storage\n",
    "N_tot = 0\n",
    "# Definition of parameters of the random variables (uncorrelated standard normal)\n",
    "mu_init = np.zeros(dim)\n",
    "si_init = np.identity(dim)\n",
    "sigma_t = np.zeros(max_it)\n",
    "samplesU = list()\n",
    "# CE procedure\n",
    "# Initializing parameters\n",
    "mu_hat = mu_init\n",
    "si_hat = si_init\n",
    "# Function reference\n",
    "normalCDF = sp.stats.norm.cdf\n",
    "minimize = sp.optimize.fminbound\n",
    "# iteration \n",
    "for t in range(max_it):\n",
    "    # Generate samples and save them\n",
    "    U = sp.stats.multivariate_normal.rvs(mean = mu_hat,cov = si_hat,size = N_iCE).reshape(-1,dim)\n",
    "    samplesU.append(U.T)\n",
    "    # Count generated samples\n",
    "    N_tot += N_iCE\n",
    "    #Evaluation of the limit state function\n",
    "    geval = G_LSF(U.T)\n",
    "    # initialze sigma_0\n",
    "    if j == 0:\n",
    "        sigma_t[j] = 10*np.mean(geval)\n",
    "    else:\n",
    "        sigma_t[j] = sigma_new\n",
    "    # Calculating h for the likelihood ratio\n",
    "    h = sp.stats.multivariate_normal.pdf(U,mu_hat,si_hat)\n",
    "    # Likelihood ratio \n",
    "    W = sp.stats.multivariate_normal.pdf(U,mean=np.zeros(dim),cov = np.identity(dim))/h\n",
    "    # Indicator function\n",
    "    I  =geval <= 0\n",
    "    # Check convergence\n",
    "    # Transitional weight W_t =h*(u)/h(u)=I(G(u)<=0)/normcdf(-G(u)/sigma_t), I*W when sigma_t approaches 0 \n",
    "    W_approx = np.divide(I,approx_normCDF(-geval/sigma_t[j]))# weight o findicator approximation\n",
    "    Cov_x = np.std(W_approx)/np.mean(W_approx)\n",
    "    if Cov_x <= CV_target:\n",
    "        break\n",
    "    # compute sigma and weights for distribution fitting \n",
    "    # minimize COV of W_t ( W_t = approx_normCDF*W)\n",
    "    fmin = lambda x: abs(\n",
    "        np.std(np.multiply(approx_normCDF(-geval/x),W))\n",
    "        /np.mean(np.multiply(approx_normCDF(-geval/x),W))\n",
    "        -CV_target)\n",
    "    sigma_new = minimize(fmin,0,sigma_t[j])\n",
    "    # Update W_t \n",
    "    W_t = np.multiply(approx_normCDF(-geval/sigma_new),W)[:,None]\n",
    "    # Parameter update : closed form update\n",
    "    mu_hat = np.divide((W_t.T@U),sum(W_t)).flatten()\n",
    "    Xo = np.multiply((U-mu_hat),np.sqrt(W_t))\n",
    "    si_hat = np.divide((Xo.T@Xo),sum(W_t))+1e-6*np.identity(dim)\n",
    "    \n",
    "# needed steps\n",
    "lv = t\n",
    "# Calculation of the probability of failure\n",
    "Pr = 1/N_iCE *sum(W[I])\n",
    "# transfor the samples to the physical space\n",
    "samplesX = list()\n",
    "for i in range(lv): \n",
    "    samplesX.append(u2x(samplesU[i]))\n",
    "#return Pr, lv, N_tot, samplesU, samplesX"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "***Reference Pf:  0.0331  ***\n",
      "***CE-based IS Pf:  0.034581796256473715  ***\n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# reference solution\n",
    "Q_exact = 0.0331\n",
    "# show p_f results\n",
    "print(\"\\n***Reference Pf: \", Q_exact, \" ***\")\n",
    "print(\"***CE-based IS Pf: \", Pr, \" ***\\n\")\n",
    "# Plot samples\n",
    "if dim == 2:\n",
    "    nnp = 200\n",
    "    xx = np.linspace(-6, 6, nnp)\n",
    "    [X, Y] = np.meshgrid(xx, xx)\n",
    "    xnod = np.array([X, Y])\n",
    "    Z = g(xnod)\n",
    "\n",
    "    fig, ax = plt.subplots(subplot_kw={\"aspect\": \"equal\"})\n",
    "    ax.contour(X, Y, Z, [0], colors=\"r\", linewidths=3)  # LSF\n",
    "    for sample in samplesU:\n",
    "        ax.plot(*sample, \".\", markersize=2)\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Improved Cross Entropy Self version"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "CE-based IS stage: \n",
      "\n",
      "***Reference Pf:  0.0331  ***\n",
      "***CE-based IS Pf:  0.03184653062407222  ***\n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAQAAAAD8CAYAAACYVXqwAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/d3fzzAAAACXBIWXMAAAsTAAALEwEAmpwYAABxWklEQVR4nO2deVyU9fbH388wbMMyDCAg+6bgCgoqornvqZE3K0srrVvZcr23X92yure7Vbdb2bUyW1xue2kZlZm55IYimyIqi7Lv6wzbzMAwM8/vjwFERSXF/Xm/Xr4QeOZ5vgycz/d8zznf8xVEUURCQuLmRHa1ByAhIXH1kARAQuImRhIACYmbGEkAJCRuYiQBkJC4iZEEQELiJqZXBEAQBBdBEL4RBCFbEIQsQRBG98Z9JSQkLi/yXrrPSmCrKIp3CIJgAyh66b4SEhKXEeFSC4EEQXAGjgDBolRVJCFxXdEbHkAwUAOsFwQhAkgDlomiqO16kSAIDwMPAzg4OESFh4f3wqMlJCQ6MRrhxAnQ60mDWlEU+1zoJb3hAUQDB4ExoigmCYKwEmgURfEv53pNdHS0mJqaeknPlZCQ6IJaDVOmwOHDAAiQJopi9IVe1htBwFKgVBTFpPbPvwGG98J9JSQkesIZxo8g9PillywAoihWAiWCIIS1f2kykHmp95WQkOgB3Rn/mjU9fnlv1QE8CXwuCEIGEAm80kv3lZCQOBfnMv4lS3p8i15JA4qimA5ccL0hISHRS/SC8YNUCSghcf3RS8YPkgBISFxf9KLxgyQAEhLXD71s/CAJgITE9cFlMH6QBEBC4trnMhk/SAJww6Bp0bD+2Ho0LZqrPRSJ3uQyGj9IAnBdYdRoqFu7FqPmbCOPz41nRdoK4nPjr/zAJC4Pl9n4ofe2A0tcARo2baL69TcAcHvwwdO+Fxcad9pHieucK2D8IAnAdYVy3rzTPnZFZadi8eDFV3pIEpeDK2T8IAnAdYVcpTpr5pe4wbiCxg9SDEBC4trhChs/SAJw86Ctg/0rLR8lrj2ugvGDJAA3D+mfwfa/Wj5KXFtcJeMHKQZwQ2LUaGjYtAnlvHnIVSrLFyMXnv5R4trgKho/SB7ADUlHurBh0yagvX7gq3iMA+8DB7erPDqJTq6y8YPkAVzTdDuT94Az04Xnqx+QuEpcA8YPkgBc01ys4Z6ZLjxf/YDEVeAaMX6QBOCa5mIN90zPQaofuIa4howfpBjANU2H4f4W9x/OjgFIXCNcY8YPkgdwQ9LVc7jYOIJEL3MNGj9IHsB1T3c7BLt6Dr3hDZxvF+L5vifRzjVq/CAJwHVPVwPvrieAct48PJ55+rQ4Qk+Mtuu9zici0nLjAlzDxg+AKIpX/F9UVJQocXG0qdVi7Zo1Yptafdbn646uEwf/b7C47ui6016j1lu+p9ZbXlO7Zo2YGRYu1q5Z0+33RVE87V5nPvN845HoQl2dKA4bJopg+ScIorh27RV5NJAq9sAWJQG4zjjTeLvSnSGr9Wpx6falpwnDmUa76vAqcfD/BourDq865726u7fEebiKxi+KPRcAaQlwjXIuN/18Lr2Tns6eAB3ue3xuPPvK9nGLzy2dzUIulF0wajSYP9/EIp84VHaWa3racUhqTca17/Z3QcoCXKOcqwiou5z+mdd2GKveqAdgacRSFoQv6DTmM1kQvgB7uX2nQHT37K4dhzqEJS407qx7djwbuDkblFxHxg+SAFyz/JYioDOv7TBWvVHP6iOreSrqqXMaP5zdTai7Z3e9Zv2x9ec08pu6Ndl1ZvxA78UAACvgMLD5QtdKMYDu6e2A2oXW7W1qtVj99jti9dtvn/3M5lpRTPivKDbXnnWf/Pp8cen2pWJ+fX6vjPOG4Cqv+c+EqxADWAZk9eL9bjp+a0rtQuttJz3MTTKjqKjvNp7QsGkTtatWUbvqvbOf2aV/wJnr/90lu9lXto/dJbvPO76bpkbgepz52+mVJYAgCL7ArcDLwFO9cc+bkQu5/V2r+prs4YWEF9hXtg+wuOKaFg2bD31BzCEdB4crmJgh0vTfVWiTk9Hu2Qtw1iYhs04PiGc/s0v/gDgryzxxpnvfnZufX5TOztUvMnnpv1DuSOuMJSjnzbsxKxKvY+OH3isE+i/wZ8DcS/e7KTlfdF7TomHHe8s7PYSO6P5U5SimJmgxaiyBuaxP38P47jqyPn2PXUMFPJ55Gs/nnjsrc9DxvOb7buWl/hmUpL/d2S5M06JhfcEPaKLuw2iQof3f59iV1aH93+cYNZrOeIDKTnWWF7Jz9YuMjc9jz3+XY9bpcH/88U7jv+EKhq5z44de8AAEQZgNVIuimCYIwoTzXPcw8DCAv7//pT72hqa7KHt8bjwfuSaw/N4xpA5oYYLfLACmJmhp+u8q7K3tibt3Ht8sUJPlmUHQpKHMHn4PDIcvcuOJu3ce8i6BwI5nHCg7wPH8RHaktbK41Rb5jOdOi+TPTTLT9N9VmEIEmvJE7K3tT/MiNh/6gpOfvsfmRToWxT7O5KX/YicvMt59FLWr3sPjmaeRq1Q33pbkG8D4oXeWAGOAuYIgzALsAGdBED4TRfG03lOiKH4IfAgQHR0t9sJzbyi6uvfxZWen0jrc7ZL2yL7RWcHiwYsx+miwt7a3LAuAw4Y89gUd4g8MJenN5ZTc0o+3C/4HwCKfuLOe8cCgB4jdUkRMQgll/k1kpT3K+IWPQtRTxIXG4eQDB8oT+cQhEWVMLP3OMOCJGSLRu8zYtqVhHKAhOCCS4H9vtvw8Ku9Og7+htiTfIMYPvSAAoiguB5YDtHsAT59p/BIXpmvufcIdk0ipTGGC34TO73e43QUNBRyrPdb5va6GFX9sfWfRj9eeLAI+349Jp+d1xRj6TxjGjveWE/DpHgDi7p3XWScwOXAqWtZRfiyNgIwiTqgLWfyPz8FOBXYw9pnXqc2NZ2xoHPJ2t7/DQ/G6617Mh4+i3bOXhk2bOsdyQxl8V24g4wepDuCK0JMtuV1d5B9KLOv7EV4jCFIGnXZdRwS+u+91Dc6ZB9WTInuNIYoQtB+s4wSwwn4ffxseTPCkSdjaqbCX27MibQWqgfczZvw4XB+8l+Sv/kml+3E0aWtQjXsWOLtOoGuhkb3cnrl/ew6HLSPP7d5r6yxZhciF13dPwhvM+KGXBUAUxd3A7t68543AmZV13QlC1xkzzj4OgLluE6hbu/a06+a6TaBvaRIjpk046zmnGWpfFTNeeB+jRkOlvT0lA1t5co8R1aH9NP/6K7YPPkhcaBx6ox7HHw+h3bMfh5EjKbl7OquzKmmzs+KxLvc2ajRUfv05u4YKTBhkiT/ojXrLUiUKFp9vtu9IKQLGgfddn9mAG9D4QfIArgg9bdLZ1bVePHgxdWvXnn3dll8tbrzrIBhqvuCsKlep2DVUoODTdTjGLcbDezTK6RNg/0pUkQuxl9vzqvtBfj8zkMmNaqxb2hNDNorT7tOwaRNN/12FECKQ8AIsjn0cTYvmtBLiM+n8eQbMRgUQuZCGr67DBqU3qPGDJABXhPM16Txf8K/jOsdJkzo9AeX0CVCYgNK3BuPmd2jYmo7yqRXIbcynudl1+Yc48O6zFEwfhW9iCYt2mXGKsEN51zwa/vMESrYgN+iIG/0oKZUpnMzYQ8wH6xj/4D1QF8DkCbGn/QzKefNoSNxPVEIiDkk6ig+u5EhpNfrxNiR89wyxD72AW9/TlyRdswmLBt5Hw1ebcJw06bT34JrnBjZ+kATgqtBVELrO8nH3nqrlN2o0aD77HBBp3PwTtassBT3etwfhZrUJHJ+jTh5H9caDaF3XcDTvZwRNIaPuqcft1pdIWfU8oVtKSdSX89VQgb8uGs+Uu+61eB/fHYIIe9wQUdmpeHnsy2xWfIFThEhm2WHGxudRWfwCPi+/S/Ovv3a66/6vv0nl15+TWXYYv40HCAUacgRC80RSZK8x44X3T/s5T9tA9NHn1K5ahVmnp8+TT1ypt/rSuMGNHyQBuCC92VOvu3t19QbkXdbwdZ+vpXbVKgDcH38Mh/HjLJH2yMG4Tf0HRC5EGSmDwE2kFR4geEcFYEtO827Cht/HiWnR5Bs0qGaOZ6F3IKPCF4AejHVqFKOicZwTAiMfASyxg0Wxj0Ms2FcUcCJnKapD+ZT87SXaklJoSNyP/+tv0tBSz8+FW9noUcCyeaMxt/SlcbwNuRklxC559qyfV2Uys7ihEUxmitszDo2pSag091776/+bwPhBEoCzONNIe/NQje7u1V26zKjRYNbpcV2yBBABAc/nnqN5ZHukvSNw6GC5T1TFJLJ3zcO1tgVVTiUp617jI9/9OA0UWbw3k7gH7sH8+SY09XWo160HYFd/B0bNluHU/vMyaxJbCrYwMUMkeMRk1BnryO1jpDZEICohkYZNm0ipTGFsfB7EhRD7tzdP7TC87eyfVdOiIX7Xn4k7tAkVsGeUAmGHQFRSame6UNOi4cvsLwHOu135inOTGD9IAnAWZxppTyvYzrdHvoML3avjHlMTtDStWoXHM08DUP36G8gU9p0ZhJp33sGsb0Fmb4/z7Fvh118J/vvLVPzzn7iOm8SIJQ+xtOpnbNd9S+y2PHJzn8HlWCmF4zxx9jGi6+tJ8+49pDUsI8JvBLWr3qOoMoWs0n1E7zJTNncEwWNHUzExhI9CMlheG0O/efMY0TKJFGDekmdx0lu8lK7eTMf457pNsIiQaxIMn8fiyIXMtpKx+QVwyji17yA+N57VR1YDYC+3vzb6B9xExg+SAJzFmUba04KWnjTCuNC9Ospq7eIWM+Xxx2muKudk/Un6L1mA0qcGtHU0bIqndtV7na/RHTqELjERh/HjsK+sR+7dl00nN+G38wj9G5oxAyoXOfmDXDnSWkVcmRxFYzO+TUBJCubpBhzGjibqd49yosKPzbZb0KlT8UkQmRo9HG75P2LdJnR6RTNeeJ+6igKSH1+I6lA+ALJ75xGfG9/Zf6BvaRIBn+7hr4vGM2rxq2CnQgWdy4wOOtKQHf/vjiva1vwmM36QBOAsLraCrTcaYXSU1TpF2EGbDt0nX+ADHJlVwWabbDBkMmPKU+Tnj0R1vBRVdjl2A8JxHDsGx0mTqAoPZXvWD5SnljI2QeTgcBOjPI0UFpcRVNxG9kRnqiKUeB4poVwFpQMc6VObTFCaLQ6jx5AdUMa+YY1Et/pj09YH6yY9i3zuPcsrSln3GgGH8ikY5Ir7mChS3lzOR64JLBz9GE9FPWWpUfAaQb953e8/6PCSVHYqHot8rPs3o50rdq7hTWj8IAnApdNe5aaKXHhJLqxRo8G2TcT28cdR3XUvmlefBEDvbkft+FGsrq8EzWEO56ziYP9DOPmK/HXEeDwWzbes3X/5iWO1x4j5pYT60WY2jLWif6kVYpUVAbRxJBC+GaqltO8QlsaMZYftXpyTylBU2XJojAdjq8tZWmBNWLU1Y737Y0jajjopldbcXNyXLsVh/DgcJ03CqNEwUBHCrzML+bB/KX/99v1Ts32Xdbz67kWsTS1hfrQDrg42wMW1C7vgEqw3qgxvUuMHSQAunS5VboxZdtG3sTTneA+nPz7Op2XxzH30KRwKl0NGMVMrvNDHLAUsQuG7bz++ir6MmN6XHyq2cPLT94jeZaZ8vBMJE2Woxgxg+ElHQhNSwLcvlFbQ1N+LMFc5BZkHqNmcxH0yLdTaAlCmrUa3/wvkwDQgdcxB8scITGvyhz17EQ1t6BITaRw8BJnCHu0H6wgZFsDi2xczot+8bmf7jaklvPpzNgAPDnWlYdMm5s6aBFHdeEnnMeILemSX+v7fxMYPkgBcFKetS7s0zriU+5l1ehweWcIKr3S2pyWR4nMLT7/+GgUfvoUs9wCz9cPwjLuDwrdfwnxABMqh6gPmLriPw2ZP1KFNbAjT0mwvsLzAlWkPvECz/6+WpUH8NwTkb2Py0cNU7O6LSm0EbMHVHtR6DNEDsG50pC0pxfKjBI3HGDcQT6dhnPjsfQJ1jgDomjT4LLyXnJ2bcD+Uj9++k7iNC4JuqhmnDpkFhDM/2o+Grz6l+vU38OAcJcOXYsSX8v7f5MYPkgBcFGetS3v4R9tVODru09Eso3bVKooWjWd7QxJBzkGdnX48q1K4M0FEy2EqM7IwJ6bQaAe1o/vx0ahWHt2Vhc+eCgAeD/BCXqYjOHs/ze6bkS1eyBe58XjWHiNoeymlocHsub0vM+MrcLIRqGlTkzDKGsW8KKZFPsbuV5dRm5GCOMKTxYMXW5p/+u7n/9J9GAXsqtnPbfZPEPbmu6Sse40RXXL/HYbfEQhMqUzh5bEvo7KzwXghN/5SjNjBTZr5LwFJAC6CnqYGz1VTsOnkd0zwHY/x3XWn3cd2ShQx2SYClYHMCJrBTM/R/CruBwyogxyw0+kAcG6B2qpatgtN9NM5MAGwHx6Jjb1AYPZhqn2MpLqm0JRtxeojq/mnth8AfXKbUDg3Ue3hisNxNW7ICVCING5NwOQxk6ATpfgUglWGnvU+65ngFoleNQz9WE8K8+qpVBezdc9appWqmPLYq6dF5TsyGEELlnCLzy3sK9vH5kNfMCvLDuW8ecjuncenufHE2XeTJr1YI75YJOPvRBKAi+BcxTtnpqs622Al7mf/kihmzZpFwsnvWB9QSFZfL5764+NsGdDCbHuLJ/HDoVUcz0+kT8YBPBYsYXfRCqJ9KkiY6M14/+m0fNzeTsvPm+LFsfi3HaLaXACAYGePQAsAOlsHVqsPMajalqURS2nd9XXnOEcWyHHXqGkK6kOTpgatlxPjvi+kqmA5hmyLJ1FanMGKtA3gEgkFuynJcWbCCTOBgK11JtUJiaj1at4KL+AR/wVUbPycSCt3oneZMYbraRs/mGE2IYxZl0Z1QiIAP4ySXRvnBUjGfxqSAPQSXZcFjXdM4vWU13l6ysMoEkajS0gkn4P85e7jPPLUyySnv4uPazg/BMpYfWQ1ibrjvDz2ZeKam3FP0hF60JZc7yye908npq8zB0NMEORKgC6WxIpEsmL0HFfH88CgB8ideYg8TT4hBxIZ+MgSyoaqCcwo4qWtLvx9RiLWMmuWFlpaNbZZyzje18h4DSgULjgV1OBTa4dmsBL5vXdjyH0TG50Jq/xClobUE+fRly9dQ9g9tJYQWz+mBkzFM+4Omn/9lZfdEtlXlkTwT0e59edakmYGcGKijJaAQrYf+Zp/nxhOa0IyNqOiUc6bR5w9YNARp662BP2uRl+ADuPPTodYG0g3wjsf3bTGD5IA9BpdlwV/STnVrfelAeHoEhMJtvXlm/ZGHrHesaxIW8HSiKWd7vKX2V+CnRXW00cxLGoYsXfM56mKLaiL93Ow4ShtzvZEPfYiRf++l1/aGpkq96H/z1l8636EI1Nhcf8QFj/wEKK+BV1GEf459SweEMJ69pJnZSYMKBkfhtfJk4CRoqZiwgb0pS2rAhcgf92H+OtMNNpBnb4ZwXEETkY7pv6cx65Jvvx3WAXZsnSWvpyF09N/wKe5nhiFwNTR91Hi+D9inQOxGuPK2EGzGFKyG+HEbgDy/G0IUVkKgRbrjWh2/5v1jSeIm/LGlS397Trzx9rAVDuYP+emNn6QBKDX6LoseGbEM50fZVk/ATA+dCrGKHfLzriqIkj3ZUxJGbMdghg9ahBNwOqsjwE4PEDFyyoXFvd9HM3Ae3DNjWeC3wQOvP0yY3/REHHIlupIW0K27+ePdwxh+zglI0fcTsojCxCa9SiB0lAlI+95jNL3nyWsTKTMTeDk5FD0TVmEFUG2eyuuBitc2sfvPWwseVYJhGTW41wOtj+V0zBtIsbDjvRzaSQ7RkbEV4dpzROp1FXx7S1FLK+NIdOwh1FZxbQeO8As16dxiw3CxdaFb6arMclFYgZ6Urf6HZR3L6RpwGxeKP+FfXXJkBt/5ZYCZ7r96UaL8f9+5ZV5/jWMJACXgSBlEO9NsZTrGhfei0xhadq5uD02kPTZcmJ+LsREIVpgdPoIdj0YwQODHqAy8xARb+1me8MqJlcrcexTx9waN7ZEbGG1+0H+7gq+Na3knTzJpxNlDBgo46NpH3HgnltRZRR1juGAZyNVOe+SG2pmYhr41ImY1uzmzckymhQQYuuDy9YShIhw6htLqW8s5O2xjUxyEggrEwn1csWxTx3amQO5pfwwo5IDaLxvLLbbywh5+AHeWPEKqvT9pO/fT2shKAb6WLwgbR3xu/7M23XJPDViJLJP/0f1ESXYKPg6qpV9uhJi+sacVgvQk30UF013a/6b3O3viiQAl5munkHHwR2jbHxQh/dF2R50a0tKoUCRRtCCJcz5ohZToYjVR/uoLiymwbuF1nI7Yp5YQsvQxWhH7qcgv4yq8c4EZBUx1Nqd9cfWc8tjj9P44j9xGTYCXXkpfY0l9EuUEaVzxLOhEQD/vCbmh/pw4DY/vGxD2dD8OaNLC/ArbEVZcIyH+9uxYmYbEzJEwncVUJWdif2wUQQesQUqkR3agdfq1Wj37UOVXoS8TwtBgjvQjGLMNOQqFcat/2bqZ1uR3z6Z2bHP4yTvBwUOFnEosuz8G+Yx7FTFoNbA8p1rOaD5GHmjrjNr0Ct1/1LA74JIAnAFic+N76za854dQXl9CcpKOZp+nti2VeP9SwamwmIElQtHJwcTsFlDmbcb+4PU9O8nMO1/x9EdyGLDGAGrPD3TE6xIcM1jY8kuhmx2xqGyHrO6HqsjWdwCQDPH/KApwA2nIsuhH+XN5aRWVREbNJhhWn/cCy1eQ7kKBp1oYbmVktIlU7FpOok29Qi2UwZhNctE069HUWjqKV66FLtplq4+gksAypNVOIwfh2rJ7zFqNJR/cwJtujMt/jXUz5ChmvEcHeG+BeJ07EvTiPOfDlgEcfnOtWxLcWfW8DuZ+NNBqr9NBXqh7l8y/h7Rm2cDSlyAOO9xDBkxFNvR0eyfMJhfQqwB8HD1584EkbBSEUXsaERNPc7f7cahqgmf1Dq83IKIOqpHd8CSUrMT5GwZYiZhuopJC5fz6g/OOJTX02AH+UpLKrDB2XLvwSWg1LV/zQ5K3EVWfygQ+MpXuB8uItsHGj0c2DDTibQQgdCsBqZvKkQRNggAc2kGe2SNrJgro94eRE09pZnJABQO8Mfjmafx/sufkWd+QsNXn6FNSKRgkCvrg0p4Z9fL1K1dS2tBAXVr1+KUvJHFqd+gytoMwJfZX3JA8zETo0p53cUBe/Enim4NgFkWgbnoswUl4+8xkgdwOWmvcTcGzKbhl93gVYpqz0Fak+y4ZdQojA8+jtMIkT7Tb6XyH/9El5iI04NLMAwfwB7rVMZ8V06j3si3XoUEabzwA8pUsHOgiUj3AO546R3M3+3GUFkPgLIFNDmZONx3O/ZZpehTUsDKzI/jbJm+T0RZrePBbeCib4O6NnKD7Ohb0YJzi5Yp+8BGJnDMDwYnpqI9lI4caD2WxtgaO2TTffjkCSOq1BraRrkybmgAsQ+9gNJkRvOPxVCXh8Pc+7AdO5qi23wYZFvJ0hP9qX73jVNnEy57rLObEdC5FXiQrz02Xrexd/M2/hFaytKCLczaYodZp+vc+txjj0Ay/t+E5AH0Imed1pv+GXU//Z3kJxZS/fob5HyayIoIBbl3jWDXUIFZQbOwt7Ynu62UeEUOAEdrjpKtyeFX83GaRgQytKqehzTD8bh3KXlh3vho4EntaF6e8zmKBhnNCfupmB7J96MEjgdAYJGJzJxfMGsbQSaASUbELjUr4kzIhzWTPN6WFiso9bBCVW9C2WLxDHyarOhfJOIos6LFyRZ5qxGDkx3CsCgAxhebeabgGMeGG9mvP4612XK40463Hqd2bw21x51J//kwrQmJlGzZRKx3LEH3PoT7449jGxJiOSPw7oWWir/2GgB7uT0Azjoo/+d/CPipiL+qxzIxQ2yvqRC6PdPwnEjG/5uRPIBL4Mzqv7O2u0YuJGXTzwRkF6HzcUWVXsRTQ8aTf/tQVh9ZjefPh/DbeIDdh1z5enADTTIHTHWp3PmDyOK4EBL76zGECOT6GGh85zVqlOVUTh7MA4uXI0/7hOKPUtEdTMXbz5ucOc60ZjRy3Bem1jjQesIiKHo5+Kph8k4DB2cHMic5kFZTKr7VJsBEqSvUDvYmcm85lc5wxMtM6swQYr/KpDXCh4NexTiECERlVXCixYvRxSaGVxjwLzlAivw1VviU8H+BVpjD+vFWwAmeHDSGAZOHMTs0DrnJjKw6jdqNBzvPCOygQySXRixl5kEzTXv24jB+HFMeexWg87izHgcDJeO/KG56AbiUFFTX6j/lvHlMTdAiH/oosztSXA5ujHh6NSmurxH1u0eR7U/DfUwUbRvf5Q/jHyBcbUbLASb5TWSb52EMQ6LwMyvJ98qgvCqFCc0e9M8T8d1aiGe2JZJ/Yq4V8pMbYM+/sR80nJosE4qScmb9aFnvl0zsh0phC9SgtYYyN8BaICpPRP2pBm3MYAxujijqmikKceTE03HEpdug3bsOo8LMbUkyWux0pI5wZuz2PEKHNLPf3Y4Cg4z+BdC/AMAKIWowZTX5zNc74F/YRNaARkKHjmfwiGfwM7tQ+b/P2axKZpZpMx7zb+ucxc/cNPRU1FPY3zaBY3XHGLHk2U6D70mpdSeS8V80N70A9KRJxblEomv1X8fBGbOeeRpV7Klr3PoGdbbL1gQGsOlvixgbn4e1TI73/c/QoM5EuXAxcTl2FHz+JVkjBtAvt5E7j4g4LJlE5q0HWOFTwrImGcFlZuxry6lrCMR81JHDygbeuMuaqXk2BJ6wBPr8k4sRta2Uq8BbA/0r4UiAaPlcbYItuzkeCBF1IAt24Q8jH6UuoIif8r7BPacRX6D5cD51A6zIj2qlGkdikiAjAnLl9oQW6LH28yVFoSZ2azkHx3uSMF2OfsZo9pV9D8DzuQNp+u8qsibKaJo5G3vfaEspcIuGFxIsVZIxfWNYGrGUOO9xxB/4Fyt8k3mqbjeLzzhboINzdgaSjP+SuOkFoCetvM4lEl1z/D3ZIRifG8/6gEKIC2HekmdpOrmBH1y3E5cfjtdPexi7y0xacSaeeSL1g31xrz3BiMdfwTr9LzTJLf331GU1fL5tD1OPO+OHnrtsnFkboeXeVifKmpvw0bSSFWiFyWTCWwNNNmBrhBxfiyBUepk4MskDrz2NDLM5hPGLh0jJaubTQVocg2U8+42It1rGbUkimycp0RlaiUHEztrAtHE2VLXo0ZaUEtlg6RHg6urNi+FHGaG3I8ZrLPvK9rFr6CAm/vFxBgwVaFIIrDiyuvOkoX1l+whyDuJgxUFi3SNR/fwccXk7YPi88/4Oun1/JeO/ZARRvPIndUdHR4upqalX/LkXy8UsE7p7TefXvMehytrMp/pGsr79ipYpI3hi0GKOf/gv8mIGYp92gglaW8w7ciiZ6kvKvRPYc+AL/rBLQbmbgKqsicEllucUhilJdm/kzv0i2yY6U9/WRP9SkchCaPZ0wrGqCYAjgdDqasKhxgoRy3Kh3tdMn9Y22mpsyQ6y4vW54NFk4t5tYC9Yc7RvGymDIeKEgJdoxbHhch4qLoetLti0ypD5+eD+yUe8snMN0T+kob3zcazCa8/6mTcf+oKJGSL2t93KloItxBzScXC4gtnGZpx+/jcNjREol69F7hty6v1T5xF/4BXiYp9H5RrCWUjGf14EQUgTRTH6QtddchZAEAQ/QRB2CYKQJQjCcUEQruDG7itDx6GbqvajsU+L9J+DzYe+4OSqN9h86IvOrznpYW6SGafkjRg3/40x7+9l0S4zdjtS2GPMZ+ZfNjDwaDOVtUUU2Fjy+In6MlQyWwYHj6berOWWgxbjN/dxRa+wIjCnAXuZHG2EluAGPbccsxh/XrA1ZSEydkZajD9xjBuDs6wZVGIx/gYXMy6lMtpqLG3BwgtMxB2ScccegcGlEFLSRlwyLM50ZUStE+P2G3E6ZmBrQx9sWi1/Nmo7I4ffeonff7aXyIwiZuz5zPI+mcywfyVo61DZqZiVZUfTf1fBll+ZmCFifHcdE9O0qExmGphF9c4qS5q0C/EHXmFFXTLxB145+809h/Fr7rm9R78biVP0xhLACPyfKIqHBEFwAtIEQdguimJmL9z7mkDToiE+8wvimpuJd3RkxVHLmr7rcuDMINWpDr9iZyvsjnWsJsyDGlM/XHJLsR07mgGLopgdGofmo8/w23gAPyB/Sh2fTpQh+rVw68f7aMkow1wjgq0ttLYiq1FjD1QpwWwwUqpxIqy4DYBSV8gPdGLqr2r0gVDiKXDP9lYUejNN9gL7wkWsBBkDy8CuGRocQCYX6JffRngZoGgDnUWAgjNbkTVqyQo0kx0iIzbbgZ+HNxKZL6PvySpcTlbR4UM27zuBLj0dhXYPmp1/I16TQdyUN05z3zcdXUfBRBlB7of5/Z4tKMcvh9BJp1z79tqJuGGPwWGIi33+9F/GOYxffddClm97mwOaj8/63Uicm0sWAFEUK4CK9v83CYKQBfgAN4wAxOfGW4xerSEu6kmIeuqs9eqZQSqvu+4FYNdQgdktGlR2KpTz5qH9ZQPajGJcgIJBrvj8eTGJBZ8wNrEWR4MlL64IcmCASwa7PQYy/6s6dOoTABitzMhbW2lztMO62RL0E4HbksT2/0GVIxwNhDZtA+mBEFkIkYUi0IyujzNH+6vQicXcceDU0q+Pls7XAxhd+iDX1dNma8a6UcuRAMjxtSIiS+TW/Y2olWZcG6A2OIi2/i74luox5ZxEbGmh5JlnKBrRF2PjcL48cRCfA8uI0BqQ+Q8HoM3Znh9jZDwQMIj3HKzBqY2ZwaX8UPAFE1pi2b3j/4grOIxq8t9YPHvt6b+IduNXZ+exceQ85h/bies7K2DJEjbuyWNbkj/TRt1/Sa3ZbzZ6NQgoCEIgMAxI6uZ7DwMPA/j7+/fmYy87caFxlmYWzc2ooh5icUcziy7dbLs7UGT7WAdWpK3A6Kxg8eDFyFUqHP79Koff/D8KzDo2DG3A/fjrFDQWgE7H285DaY0bys/KA2S4BDL30xqc1KCzE1C0iOweJMOnyUzIjGEUbzuOTW0jXg1gCHSkSa3FrVFEo4SZhwBMlHhZUeAPLSYTA8pA52JN7P4i6jyNFPvIMLhaIzbKyHVrI7ASBpRbfqxk9waa+tmxJ6CVB5MdKVA2cWeCSG6gDYQ64JprcbHL3RoZFjId09b3sQ9txtjsS/FAd/w2WZqL/tvdDvvaFNQAHOGn0l8Zs/w17OX2GNVqCn5OY/fQQxxDzz6FgpS8n9hnroGgYSw+sz9gl5l/48h5vDpxCcyfzyNL7gZgfrRf+8c4VHY2l+cP4Qak1wRAEARH4Fvgj6IoNp75fVEUPwQ+BEsQsLeeeyVQ2alYPPxxS236V11y0V272Q68D7NOj+azz5DdMZuvq37GqNHwSvEoBk0Yxvpj64kLjeMH3RFWjKwFYKoyhsVFgaz3deWJlhoadiSxb2osBWnOuOfq8FVDnavAm7NhQImMw5F2NJhbeXF7NkF5lrdY7WPkRF8tMYWWt9Su5dS4/SpNAGwYI5DjIzI1x2KKblVy3IAT/Wx5bVIrEzJktMrNnQLgpBFZO7GN+9OMhGQ3IcRFovcrJrRQjTGyD40+NbiWyXEsa+Z/tiUwUcaACRNZNPstVI2NpDn/i+D0PDhZBYCgckDUaClqLGb/4ff5aPpqSt9/l6ZdZsYqh9FPMDN6ejRjwyYzIu1di9vftWPQGW7//GM7Yf585i89lRFwdbDhkfHdBAslzkuvCIAgCNZYjP9zURQ39cY9r0XOykW3z1KaAbNJem85AZ/uAaD2wE98Nq6UCRkiU3eZOQ6s8E9Cb9SzIHxBZw381AQtxtXruH1YAPJhsVQfyWeUwp7IRDMFccNwmG2mQC6jSpVBpZ8n4/xGE/BTMkGZJejs5Sj0RuzdHWm6pS9NhwtwagGfejMgQ+tshZ1cT5mDLbUDrBm1qw2HBhGdmw2FwTZ4NLVQpTPx5PcmIgvhxAgzglcbYqUtQ0rgH98Z+GWCiUpRTkBLHSHKPoglauyKNXiNVnPC1ofg/FYG5lew+/GnGes3gfUFPzDcJpSi1nIC/Bw7BaB8ZD+sCluRa6sJaprI+mPrmXvbrdhb2+Nap0a9bh0zvMcijwmEwLGgcLW84do6OPAh/OUrOJxh+Zog4PrOis6ZX+LSuGQBEARBANYCWaIorrj0IV27nJWLbu9mG39sPR+5JvCPuSMIPFKF++EiHmsUOHLXMJwiRlM5sBUKLAIQnxvfeRLuR41vYh8iEHW4iDIT+DyyhD3ejQS21DDigT/D9n0ErXqPRbEeVMsqQNxE+cghlKlK8NEYAThoa+AjqxKO3GnP7zfqUeotEXrH0AGIh47hrxaZli5SOqKZTJzYFGVgZlobWY4ityRb7pEWInB4uIph+lKyPWyxLgKfYiui9lpR4WVi1NYSEqNhjHMbRrUOmWIu3v+8h6S1rzIibglzkwrZ0riFj46s5o9bZIw92Uahn4nwaUPJUSoJdw1H+8s65gFZYVt5SZuCMUjNPFwwt1jEUNfUzCvbLH0BMOhYrDdCQy0kvw1W7W6NlOrrdXrDAxgDLAKOCoKQ3v6150VR3NIL976mONcpNR1Bp/4ttWh/SEFQKonKa2CCbjS+jz7BHS0a5K6u6I16VqStQG/U46QTUe5IY81kARdbJSEZRfwSvIfyY/lEHxbJ/etzBI+YDMDkOhmmHIuLX6muxKtLlsu12oxvo5lkH/AfLnDnfpGiQCt2jtbzu0zLDkGvEy1sG27Np7MFXvlYxLMeKpWW19c7mlE2yrjrfw1oW51wUZpwarACIKIQ2pxFSl3hh4ECR6Oteao1DtPsB9j4zt+Ij6jm9i9eY/a2EtymePNCqQPBJxupcbXCvwQUM0Yy7f/+TF1FAdnqbMJdw6mLkkFBCl57sqj+fD+K0aMByFQb2JYUzMQRd9FYdBDN0c3Y5rijKGyBw22nGb9aa2Bjagnzo/1wNmiv3OGhNyC9kQVIAIReGMt1S0edQM2ud9ACYkMDmuHBeNx262nf17RosJfbozfqyfr0PRbtMjNmrIAwoD8lg+Ss907iwXonoBGXjCJa+iTgcftwHGffReVLy9GVmil30lIZCHqlnBFl1kQU6vlP2SC2RUWSbZPBdsMxPGpM+CcWoGyBNgEcG62ISgUnpYhnveVXpbWBZkcTLs1WuDSf+lmcGqwoV0F6IIT27ceI/EZEdRV/+EFk7yCBT0ecJHT9JubsTqdFtOG7yHJcWh1R5pQzpAQK/cwEh4dh3p6DufgQdavfYcuAVv4TmszS8KEYtON4dIiS2GmTwdtyclHzr7/SZ/psnstrxujUyPtHvyZVMYYpRQL3H8g9a+bveuzYHbm7r8zhoTcoN30pcG+iWrgQvbGFX4t38mH/IiKPv87Lqpc7q+I6hKCuooA09zSsFnox/VAyyoRkcmfN40FlJFMq91CrckWhMZBefwx1aCvjEzPJ9dBj8lFhVakloghqh/kgry1CEahA0WImTj6MH375nlFHRZxboEJjaQVu3R5utVVbkT0Myg+Ddz2E1ABYZvpqR0AGJ/0gUGPCp9yK2pA2osZFYu3lREHFx3jVm7hzv0h6s5rdMb7kjlGwNbKVJoWAQWhlSHtlYjMy1g4M4W6DgKx0H9W/HCHm9ghu8dfRN7uQP2WFsnzmRNzCnCG8GTycsW033Ed8PdFUCPDBB7Rly5lzaFe3bv+piL8fzkN7dkiLRPdI/QB6EblKxc6p7nzYv5R5J1Skn9xLfG782Rdu+RW/jQewK6lFmVkKwOGcOgZtbEGX7YhCY+BIANTKrfjIzoWd2c34HbLFscWViCLID/PknyNKyJ1gT46rhtqtWRz6+3PMONiMc/ty2dZo5oSn5f9aJxNbJ4hE5Ih414NBbvm1G2VmZGP82DvLDoMcfooSSPWzzAlV2FC2NR31unUozZb6hAY7IOwkUYofCSzTMfegmVC9LdNtKjHbWARncAkM23WcJHd7nAP0OAzyIXXMYPYpFOSHejE9NoupQxxPZVDSPzv1vpTlovrDZB7/NI0/7v0e15Ym1B+s5YOQ8ai1hs7LXB1seCTaBdf01chtzLg9+KDk/l8kkgfQy8SFxtH3+yQCft7DYPfxjOqmKKVjtnKcNInGwUPQa5uYk30Qu4MnsHPTY3IPwD3Um4if0hlQ3oIwzpdcL1/8B6j4yUOk0tmZqJYSnAsE0txsSY4V2DvYzBQ3gZFZIp5N4KqVYXQ0kesnR+ZsIjhXjo3B4g7YGM0Y5WbkRhnqSjXzDxkQ9fDnjSK7h1jGqLGFz/pn8kRVX8xZtWgV1ih1bRiqAwg+nItnoaXASGmrp7rAGZVBhtZWRtvQQOb7HqDMPRp15Qy0xw8TVeBEbMD9iNY2HNB8xJ5yN1T97yTvRCneTbX8kvQ6cZpmVP/7GAZpoNwaEtvQrHmHp1U17NqWhs5g4v7YwM61v2svncp8syMJQC+jsrOcm9fgtYl+0ycgT/vk1KGX7UVDcpUbbnfHQfpnqG6fjXHVP/CuT0ONE4JMoC2nGifkyHz6oiqp4OsTDswbUkXatiTakOPT1MDQbBs86k3MLIJPJwo02wvUO8ChfmJ7IRA0YkVoiQjYEIxI5ihrcvwNhBULJA+wIqjBFitdA6Jejkkw46KXEVFmZn+0FQiQZm/HH6c1MMxLRmo/EzNPOLExoh7H/iLLdUay+8ppDmnmb+GOvPiNQB+1ib2uzkT1u4WA4j0Yx/6RJt9RPC+rpmqvFw/odqOcdy8tpYEcTVlFWm4tjpU7KCh25hv/Rn5fWQ0lWPr2r1lD/EiBlLT3kStnAhGnrf0fib70U5klJAE4i57s/LvQNZ3Zgv0rO2epuvp6Ujb8jxF31uN260udLnCDKZ3675LJCh+M4taByJvT8dlTgXNOOWYgL1zJgWGFjNhmJKaw49dlido12EH2MHeyBxh48vtGIguhyM8FqAfAsX05oHYG10ZoRM+4iHpOiq6MNLWQ5CtnzAE5pa7gq7YsC4LKZKhkDowpaUZhY80no4yUxsjw1NrzS1QDTTY2hBvknAhq47uBMm47qcIlsi/7H7HDM0mguNSGx8IqeEEuJ6g2ma8dHciR5fCXOmtcEvVEIWerqpBx1l+iCH2Y0vR+jN1VQW4/K0hugxZQf7CWjSHjmOrtiM5gos0vivtGneoTMD/aDxxspJm/F5AE4Ax60iCkx01E5AbiQieh8osl5dvnCUiyI6c1kZERecgNWhj/HI4e06kphd2j3Mh0LkHXUM3/WXmgb9Gj1NZxyLGRMZkQXChD7eqA26QJ7CzdjmulwVLAY6fm7prhDCm0bK8OVHoiltSjVprxarB08v10HNx6XOQWZQNWyY4EVMkABbWjjHw6UUZuPyfGHW2kySyCCIPr9bg7tDGnpJmjg4IJGDKTtJKD1DfquOuwPUMcg+mfcIT+mSJe6lbKKObHoQL/KXdidHYWn3rI+ENMAJ8UHeQJQOUURkxTKYYoHwx3PIbnVz9TM/1pomMWEPTBHaS4aondWwktwJo1bAwZ1z7Th/P4+IdOe1+lar/eRRKAM+iuQUjHTr+OlNXcWZMg6gJNRDK/YEX2J6DWsHjff+ivOEx2f3+C0osof+oxvEOSkc/+G80HDyMmHsTRTkZVjAwnoNZQwccjbFh43I07dzSxLVZBqasOX7WWn+sSqLE3smOcgMkKSod4kGWrJ2uMAAJ4DKpG5mJia7CcP28UcdHDAztA2SJQpXHDtf7UGPu0GVEYoaW+gZByGR+OhwX7ILTAhBFrOGnNg40Gym19GZhUxAmzmd/tb0K+IJC80BoCcss5EgiV4XKeznLFLbsS0/AIvGQl7NY1sNQ9gMdtRrHgpIbqYw3k9VPg8uLfiVVXsF4Yyh1v30dw0hFmwGnR/vlaA3pTI0anXWhaXE87RKQzBuAg1fv3BpIAnEFHqq4rHSXAHe2tPYDF58g5d4jFXLcSUGuYazeE0ophfO0r8qNPNq85BMDhIir7zcY3ciHKgTK0jWpGVR2hTHQmMu0A4xJM2JvtKJA1s2GMAIIeX7WlYq9V18iiJJEmZzNOjTLkP1Syblo1NnIZu8JEJuYb+THKhgkZIi56kQZ7AaXeEvxzrbd0BmoTILcv2BqtmLnPkgb0aDbz3Nfg3Ap5fcG5CZSt4FFVj9fXb2IuacFfKSLrp8OUs5sBsXHocj9G6e3Amw15JHpFctKvAdHBjak7j2AnU/FOdBOZLgZ8xj7OXu2zDMnSoVI3UuXqRHzkcYqsXFlltJzSW/faa6RUJDOiYiJufYNQeqSzIm0lChurzt/HaTEAyRPoFSQB6AFdo/bNI0eeN+fcIRYetw9nsW0TddWuNH33KXWDpzLkvhiylwoUfLmOoMFG5MfWEddqxsFOQf/4NGJvC6QSS7qrX01fRpzMJWuGJw0DVVQVH+OTyTbMyrIBWnBqtKzZIwrhxW1W9ClsI6gIIgqbMOgEbEWRDWMF9g8UePQXgQFFZo4EQJ2XiUlJVlQEmAgus9QBOBhEQMC5FapdZOjlZkLai4MEFzkN7kraGnW4NsiowxHVyQZa3ZLImOhJ9aglFB/aQkRyCsp6kVyPXymbMZ3Qvo38+3AxAx5eyuNH3qZ0hJYZ3nru3udNVt9GJpRZ8UTxUZhqh+53c/k2P4NbtqSQAkx57NWzG6xyev5foneQBKAHdC0Btj1ftZm2DqVPDSx7DOWcWVA0EmXAbHT+OxngH83tEwYjWGmJb8zEeHQbJ/dmsNmvkQXDH0f9xBK2Om2lSifD11rF1Jhgsn85zmBRycmDlXgWy/nLVvD+8xPk2X1FmNGGTHUWR+zsGFYlB9pQKls5GOXAyGIDgSUyTgaa2BdpzfvTRe7bKfDtBJEqRxvKFCK7h1rxoNGGkDI9x4NEhpeJtCmc8ahuxqMeinxAYw06977Eppbw/SgrfGvh2xGOzCloweSdytveLtxe9jW37y7GziCiVZqJDahBLf8F10MNVB9RUlm8guooR/CFQrsQPoiwJXGAhqfUGryb9eByBx+HL+Ej7UZMM4dx55Jnz2qw2tX179HM32Wb9mm7CiXOQhKA3iT9M+QHX7WcfuMbAr7LkAN+S0M4JRs2LJ74H0oTDTTtSsXpdxNg8Hx2//oEVUFVNCkEWsMK2ekSyEmlPYt+OUFTgOWV7sVm8r56j4HNlXjd+yA/VZTReLgN/0I9ja42NKkCCcwvwatEhtbeTL9CGc9+YaLMB6LyIM9L4JtxAmkDTTx/wEyD0JdjfqUodDLkzeAQ3EybHE70MbBlFIRatXGHqQ2DqZnMoa584eSIo6mB3CoRDxslkSYX7jjYhLXBiMxeRsDYajZ4uJJacyt/CfkJh2o9ZB7hL2ELOOYzkKI9Gp7Y/Tkjhrbh6+SB5u5nUT36JOZDa2jz34f51mW49Q3CeMamq/O5/t3GBbrUCKgjl0pxg/MgCUAvoWnREG8vJ27S86jOyE2fmTbUWMn4eXok3sgY4j4YzWefMfaHQmSjTKhU3gy45Vb+02bCblI02kAP0mQ7sT/SgFwUyTCAX7ozv7jvQd1PJEhvpDrIDo8CA575hXgUQ5M9OOktGQBfNbgYTYAV/Q1GXFrteCHZSJ8UGVDaOcZjfqCUt+BXbkdOqDUJbtaUGQzc2mTg11FwWGUmVG3PjOM1jEuwIlffytqJAscj6/Fq8Kfq98+hF9/iPXMNC2T7UNZXsvnOwcToZ6HtG8Hkb/9DZaMt1ja2jGxS8OugCMpDRnM/MDNwDmlFahqrI1BrDbiesenqfK5/t+IQeapGQIobnB9JAC6Vdncz3l5uaRsW9dSpjkHtxOfG89G+N+n7fRJT7n+G+PRXeLsumTlqM8HfJmM/xgWPiAZGaZVYJVWR0JpJakwBAEJkDPsq2xg4RsHs3HL67nMDrChtqaE1W2DsQRmF0QbS/T1YH1bLk9tFQgtE6pSg9TKgabYhy8MKgw14AP1q3PlswmB8bLYSVaQipNTSJERpMGOqsSE3oo1Nw+xQGY0U2Njwq1cfjjX0AfJwEE3UBjmgb4PKsGYeNjniFjCRpCfnc6zehkdj3uSOQ6+xOMiH+NwyVijqmaTSMPf4a4z2TMfoIqOu3h63EXoirEvQyYdg1ISQ8foHpNvXsau1gOOlZt5eMOy02fp8zT66FYf2bdqWrzud/X2JTiQBuFTa3c24Sc939grsbBA6fQLyk18TZ2qlb/UoAr7cQ/mRAmb7peLRGoGV0YgivADMTiiD9WwoUzEBM4K5itmE46c5yBifPliZPVEmFdBY4Ix9oxXaPiqqJvsQVHGcLL2BRD8vZtW4sLg+H1ydKKsHHw24NdhwJABmHYb8IJHgAivyFGU4jI4iz+0eth0t4OWcPLRVVcjaZASWQCYy/nBAQFEF/5tixElWxXHNAu73rUUhy2W1rwvHvFQckxt5Sl1CXm0Qdm0fE5Rnz9ulMUS2ufC6TwzPuuaBOpVZhZ/jqWqmrRjaSszsmvZn5kY2I7e2QjHyfuq+2kTYd18yY6KMjUG2JOQ6sDG1pMez9YU6AUmdgs6PJACXSru7qYpc2Dnz161/h+qV70Hur7jZbkYFTIlZTnm53HJKLtEEZxQDUO5jh0t2E61Tp+Hv7ELi+CNM+tNrPKRQULfhEb7Zkoh7YxUDDtqQPtSKEbJmtg0ZQajTfbRp3gXnBrxyK/E6rKavlytipSWLIFMYMevkuNlApT9onMzsHQW7h1pxd+EefAR/UvyPs8Fdxz6Fgn/+rINKG0QgIsXSKOTOnVAaoOa/rpvos6eAz6OU9Gt1ZJEOqkQNc2t0VB1PpqVChn2jFeWKfCaHJPBWWSv5fv4sTj0E1rWgsuawKZi3x/6FBLUtDbbh3DnKlfjceObOmoSVrpla53pGawdxv9sBhg8cfqV/izctkgBcJKe1AY9ceFrUWRmkhYgGlLGh4PgsICAf+Xu8R8k6C4oaN2/mcEUKaaUpxJWBqdmB4MS9DB49GsX2DPTiD6Qc1TAuSc+GMQJ7xxoJGz4Bh5BggkuUOP73SeoEGFACgSorwITc1ET6GF9Gysy0Zpdh1slR1VrhoDHhVWzF3rEmft9Sz6AqJ3QH0tCNtueBk21ED9FTE2EgWWVHaj+4I7UN71qBKi8bbt1rpDJQgV2hM9GFIjvvbKRQ1kiLrT9lpUasc5qwB/TOJvq52POl9SJEUzXZ+u0E22tx62NLQ5Y9yX6DSNDbMjGsD/Oj/YjP/dxSTemWgCx8Kdt2VvGw1Y9Mtv4STnhAH6nM90ogCcBFclp/wOAq2PMaaGvBwR151O9wc7KH/rPgxJZOYZA7nGpa0efJJxnRoqHq4FrkPqkcGNWXUU2+6BIT0SUmsn+sLUP9mjhkrcR/zmymJp7Ey68P8rFLiJg/FW0peAEng2BKSAU1J7yInxLC104V/PWglqZYO1z2QdktJsQSE+51doyLnUCArw+73t5OcLGcWY1tyOsdcC3xwnOGlgMRWpRyB96ZrucJtZZmuT+fKspR1QvMLrT0EXhmuw075w/nJ6t8NoWO5YX6Izho1di5e6Ldfhy/MEgcoWa9q4oSHzeGH3cn5Fg5gX29GR5qjdFpF/WtAZYqysIE4g5twvaWQZRPGEdBc1/KXZ7FW9rgc8WQBOAiOa0/YLrloBAqMyB/t+X/Y5adthmIMctOz08DquQPWFSYwHqPDFY0HOfPw+uZERBLsrWM/wQcZTahBA57hhkHvqX++wwoTOAncwnjoq2p1TVRaS2ndpQWwcqeAPdS7rG3xS9JT0CSHQZfMzZqGboyA00NtoQWtZF9XEm893R2RWbykKmGUpWI9yEIq6kk92Qrqb4OLNGbmdhcj0kAO3MOX8UoidCFMl5bgVuDhtoRzVA0BC//O8htHcBzUXHI9GpWmN/Dq1oPOce5Uy8wxL8Nwc6H7MBARltlcdKjHofmt0m3L+K1BCs+mPs0iyf+B1RD0fS/k8LEz0nUfsMv4WcHUSUuH5IAXCSn9Qcc+bDl8MuuMz6c9lHToiF+15+JO7QJFYBBC3teQyOT0WTjxOOJAmPc9SgH6SlSOdDUKFCq84JD2+kj+xmbCHu2xPTh3fpUMpz7sNyrFPd0Z5yyTdSHuVJ/woY+gQXsGOJFqr0M0c/A06Xe5Bv0ROVpSQsR2OqfgEfZCSr6neSf/awIazDiZG2iVrQiog3uLpUzS2zkgIPIClcVC9RtzDZNYOzBfIYPKuBdDyVrXV3wbXPnHocBTLX7O49rf88oq2wm2mWwa8RQDh8NIkSXyNgEObtHO5A75E6O91PiUprE28ZMVpins3jsovb8fT3zoy15+qQkFXGhA2kpDUQdZDgtCyDtAbh8SALQGzi4oYm6z5Lrj7rv1BbhLumo+GPrWVGXzHehg1gZPA6/1Hgashz4eqQ3lbl6Fu1uI3GkL/fK97DA/4/UNIl8VzqVW4L80bu6Q8NeZlUfI9d5AlOtNewaKiPGTmBXfxljjzTQcsQBuUHBnQU2rB9tzwsOfcly8qe1oIG02HJ+GipSZFPPXfvKae4XhM5DwxElqGIMzNoHQYds8a+xJ/X2xUTUvMkIs8igw22EVu9FVmwgL8IVG09LgFGhbSV220t4hVTyhs0H/KlpKYllwbwT6s3h4bMZVBnObcF78PWsx85LALUD46yOYQicwj9/twoc3Hhrew4rd+aiMxi5PzaIiOIiYvK28kquio32/qdF7jty+TqDCYWNlSQEvYgkAL3EhbYIx4XG8d2JbyhoKub1jPf4Z+lQqo8o6SO6YD2sipyZYejHLEPndhLVyPt5Eie8UkuYOsSR/au/JeDXGqxHD6CvYMdJ95Os8FFxy6AB7KvPokWox8VOxFrvRFi6gTtd3SmKiaIp4RsGHLRh07C+3Jlij4NYjd8hW4bZhLPL+xhRujIOKhTMpxmwwqpYQ2jyLo4MNdHvsIn+qTaAgbQQgS8GxfJ2/R7sRQ0uiZmYM+BnhRd545bx6I/f4pLVQrjbMcq8VBzrM4d3PXbhW5PJsS+f5w99l/Kf4cuImbfMIoraOmKKPwKrOuzaluLqYEPMvGXokl3wMY5jzhk5+44cvs5glIp6ehlJAHrIabn9os1n1Zl3t424Kyo7FStVI3m9KptnbHwhbja51cdoGDSbe91Oohh5Pzi4kVfTzL82ZPLXyV48It/M+kI5H7km8JeJTkx1ySRKFYwyTYnprluZbAMj1AdocnLk7UnW3LPTSBiQ0VxOhXUbrRF2pNqDn76S8IMixcPDyZ4VTWZMIaV1dcxOt2dwQBsevs7Ic7QYtdaYqkTKKybRv/QE0IDJ1Y7jE72J8Lmbf9ffw3yrvYQN3k22fQuvjnLAoSiZmc2eWAc3Y6dxZaDrMO6eHIqndggNScexPaJlunUeiV4P0B8nXIHSXR8RXraWbHcHptv0A0aCgxsVgx9m9+ZMxupOLQG6uv8AChu5VNTTi0gC0EM6o/6FCbhZtR9+1KUjTXfbiDvoLAWOWMh7Ni4QuZD1BT+wIvAAT4XHoBj8lCVAuH8l/80ayK5cAzGVn/FI68eWAiPvYcTUbOZA20BcUo9jSjcz3mo3nvfMZnFDExqZlqNWriBYjGZYaysR2YngFcG3EYfQ6IyU2NsyYNGtLIp9nMhdf+fbHUnculeGxs+IwknEqLWcBqzKz8Hdw511g+fxZ9P3xEZl8WpzPl/mB5F6yI5n/Efys28Co0LquU0n51snAf0wGXVJ7szPz+WY8Qd+8Q0gRSYSG6ynUabEc+pw/rXzJBml9bx5ZyTPHPJnXO4APh3diN7JgdbtOYBAaqGazLwCUhs2EPL75eDgdlYprzTz9y43ngBcpp1gnVH/6ROgKPI39aI7bXnQXjMQN2A2OoOJhupIS/17e0Xh30a/SGbDCN6vGU3EIBdioh5i8f63wGzG3V7gkK8/M8Vk8offwgHZDNRteUzvq+PvdQf4xcYF0GFfa4tRHsDkqp+oUjqxwk1FiNdAnqzMhP8OJch3JPdGBJFc0kj/Ag12g5sQI5ywa2ki2dGJb4eq+V3Gj5QvuAtD1X84bnQn/6iBh47vZKLtCYoDghhtzsC7tYUpJQcZ0aDDr8oOjW8fbu93ANfyZl5qW8gamz6EhJUzT7uW9xz+xK6cGv5vQzoz6/IZkaxBbTeUhqBYPtidC8DD44KZq03jrvqPIN0PxiyTtgBfZm48AbhM3WJPi/r7/rb7diwL5rpNoO7fT6M0xqMC5MbZvL4tG3sr584ml8qA2Xyc/QM5gUUc6h9EWGs9qmLLYcsDDUfR9l9EZlA/gozeBHg7sae1P6ubw3nSaQKzHxtIVvmTeOS1IZQU8O4wfxraGhneYiYsv42+QnsL7voi+gI7x0SRFChjgJ9AuMNYZPtTiPEqwWGzJ33LaxF1q/lmNIyvK8XfwYHCYYHMCNjHT8Wx5Dl6MjFDS3S6maLBIXwxaAB7/CN5w+ELJhtTqXQYQIvJA9qq2Kb2RK1tw9XBmvScPGZ4VrHvlrl87RDFYislD9/iQGZFE3eN8CNk/HKL8bcL7MWW8kqZg55x4wnAmSm4q0mHNzJgNgD6bzbStPEgKbOiGRU4lkUnvsdusiXoZdSU0LA5GXPrAZq2ZNA2qoXV9o5YlaXwSGly5y1H+NhRtyWF6p1VOOzfyuCMYrSe4ZiqspHVxlA0RsNWf2da+tWyXaHASefEhHQRfAuoNvXBw1wDQKb1EBa3lZLeX8ctzVZom3yRZSSgr3Gib4Wlg9A+27686yrHeLyFsclqMgPlvOY3hxaHY4yT12AIcGRL2yg+CRxPm1c2eo0Tz5qWMrVtB/ZtrQyyPkqR61h8Jy1jQMqPPDd2EZU/beOu+k/YG/ski30jARF7GysScmvZkVlFyPiQHgn3hQz8UncB3iwCcuMJQJfU21Wn3RuJ12Swoi4ZuY0bfUa18I9+Fdyf+i6PHN7E/PEvoXCIpuIff6H++8O4D2rE4/YJlAf0QVYl0r/jIHWXADTh0/m2IonblcdwiO6Lp0cKatUQCgPH0aekEQf7vsyKeIimcbb45RZhaygmeF8lYw/p0A9uw2NwDcmmUMpth+NTWMMw9+P4axS4yeqJty5FPtibqf6HaXRtQyvaEuLTyFNqDf09HMjzs2dgYTWtzmpevRX8ClXMKmpFH3WUgbZVHHMvxcPempcm/4HVe3xwMteT5xXKR9XheGW9RansMGvSbRjkG8casZWGfm5YGbT8d1s5yyb3Y/nM8N/k5l/IwC916XCzbCPurePBZwArsZw1tUYUxX/3xn2ve9q9kLgBs+HAK8w+tAmmTuD3A6fQUj2QV9ps8TGO435tHW0uVXhENKCNHID/H95mGE48llpCcN9mihpzUca9TnxjEiurtlLgFsoRYR6jvX7gMU0GAb5W7C+uIviT78icNRdPn2py1S1EuwYyrjWdWpzxEy0nijopFLjm1uG4P4fU4aF8F6viOXUKSmcZ6WH+NFu7MXXQfgJldTTL3AnWKKizcmRGdD6pqhCmh+bTqlbgcrwfTRmV6FQt3BJ2DHlNBN4hs8ipaiLCz4UP96rJbY5lWv3X3F/1I2mKMSRogtlnasDa1R67vHXcH27P8plTz5pl82qa+dfmTF6cPZCQPo5nva1qrQGdwciyyf1OM/AzZ+1LMdybJfbQG8eDWwGrgKlYOkykCILwgyiKmZd67+sdjZWMeKUzcQrXzrJX2ncNqrUGNtr7W3Le6avxb00lfdhIlPesxaipR/zgae5YcD8f//oXFtcfoyH+GeJ+9w8aHAZRZWqhzbmKr2yaqJZPZEn0Uo5qX0BeX4Gt/AAzmjLAGt5SzyN70r3o+xrQNmZTb6yln00R/TyOcXhoECcHV7LFqQU7xSRur8jmT9bpvGS6g3VOE3lPt5dcOx801uXENdXQqpfR4mFNtuhDosmLLP+5jDKf5GDfNibXGTjWNgUHpybqUj+hyO92AMb1cyfl5CyoBwfPeSwK7UtOVTNGppBRBXK/UTwy6ZSRdhjwvpO1JOTWApmsXzzyrPd1Y2oJK3fmsnxm+GnC0Zuz9s2yjbg3PICRQK4oivkAgiB8BdwG3LgC0MNMw1nFQe1LE6NGg7hpEw9On4A8fTX0n8XB/DqWH/fj1T1rcM7Mo/q7QxTVHWf9KD12Kj8eq0uA3f9GWZ3IWlcV4YIGn1oPpjdW8HHGVg6KOqYqPWkc/BAbi7fSduI41cNHMeiBJez917/x21GErhXkAxowOLtybOBA4ow/sa8mnOFN1UQKGZw0e7NTZUODWzL71GYahRzWtJ+5t9jcxATHTNYrnUh0BVtZHn5OJnbqxvExzvip7HnFZx+uFV/yq2hHc8jd3D8mCNXUMD4+EEYYAiCSVKBm2eRQptk8ctbs2mHA98X4U9HgwJOT+nX7vp5rdr5ZZu3epDcEwAfLgU4dlAKjzrxIEISHgYcB/P39e+GxV5EeZhrOVRzUWVNw6FPc+hyGwgTCZrzNq6wmJm8lxtg/YkBOSuR0nrDbzp1TnoDCBOg/i7gjn5FSd5B9LeUstaqnykVkTtU2vI+1EbjXhJP9DxyuyWJwqojc+is0uoVsHwTJ9TKsg70YYGVLy5RXUe38if/VxjFaZs1twtcU4EM/WRmTNQZ2C7cwrmU3rm0VnGwbimezI1+29CHEpoy5NQUYDvuiD2hkmdW3mK106LEl3/k27Kyt0MhkfKbN4YCmmB2Zlq2/aUX17C8oYuywAv44bVrnKT9nBtlOVfyZyKvRklKoZnhAe1l1F9F1dXBjfrTfWa/vOmvfLEG8S6U3BEDo5mviWV8QxQ+BDwGio6PP+v51xYUyDe1/rKrIhd0WBynnzYPCBJTGeHDvBye3oQrcYCmVTXdDHrmQH5zref/nZFaG+fJDpsic2KUU1VfzfIkVyyesQEjfRGrtblLcq/E229E0TMTOLDDZoYSIkka0OFFT5U7p0wsI9nQgf0Ag/6o/QKnzaNJ2fEWzsBM7x2m83TARhZcz71eGMdUqjR9M49FUOZOiK2FqVT3LDKU86v40fxniQL1VGuytYNyRBr7QOvBK+ALcrI38iS95pRSetf4d4YPnktJ0CF/bZPplJpJ90orjuVHIXQ+Trv2ZSeEewCD+sGEfSTW/oDct4I+ThgEWA54f7cfHBwpZNjnUIggdhm/QwZ720NKYZRd092+WIN6l0hsCUAp09bl8gfJeuO+1y4UyDRfwEOQqFW7PvQHpkZYdhMe+sewO5FQX2ykDPRmYu5vc+p+oz89ho82rxOd/TqlsI6/uhs/vfI6v941lVOsnDAqay1tJ/6XGpy+CdSHe/bQ0WJmZI2ShTTLzQEQDx22DKFFEMLR+P+ud+hHvpuJRRQuPeowkeuAcWtck8WGDt2V8JiO25Qaqjyk5OciXPw50JCcill8TwDrgEKkMpCb6FsLqf8ZRZmJ16604CK0cOV6Ml7oPQVGzGVZTzSSrbwD4s6fI87WjGNHPnbjQOP63r4Ckml+w8/wZa5f+wLDO98ayvj95an2/3/Je6mKfISNkGWH977R0WBroycH8OqYM9Oz2V9DdckDyCs6mNwQgBegnCEIQUAbcDdzTC/e9funGQzjrQNGuImKjsAiGjQNfN4xGs38d27RLsJNns8JVxRK7UkYEurItOwYPKxOvzFyCK00srXsPTm7D0NDI/wnRxApr0AxeSnm2A7ZKPZ6O2ZTa9SfTw4VxVscotBtJ+YBl5J30437bPcicHrQYQ90Rdtv/mT+Yl7C1KRCjlZwPPW5lyeBfeMdvHm1qG+Zse52ptiYmKjKwigCD7WEesD2Jymxmn2wwt1gdI6isnH4ZxUSbw3gv5DbeajPj76pg4KzHCN5cwn0DJrAhSY1G24axIRoPV3tiPWfwwZ680zb8dI3ua/rfSU5+HYeN03jteA3L/XU8Mh52ZFaxK6eGmOAqQsafnSnoLogneQVnc8kCIIqiURCEJ4BfsKQB14miePySR3Y9042H0DUgeFvQvafPRO1CYQyYzch/PE2E226Syx0YMHMF/PoMcXNf56ltJ8kvqOM5Ly3DXOypS1iH28lt1NgF0Cd/B0lt8yjp83umjVmGQ90Wqv/3BvL5t+G6/BW2pRTjl/MigQ3JfJwZxIHGUWTp70Oj07G7KI13NY/Qp6WIf7b+m8GGcay1mY11cxvPhD6Gu6yR770+xadmH+VDl5GePZI82yy+UqpoaQvBW92fCFkeAIqRwRwzy7nddw/Ro8fwdPlSxk/qx1PfHCGvRss/f8okr0bLmBA3RJMDebkjeWNLKfvz6qhrbuVkdTO7cmpOi+5vyNTx6vFRLJusZPlMt7Nm9t8S8JOChGfTK3UAoihuAbb0xr1uVLoGBDcknTETtQtGw9q1KPZm0xBhT+QEFQqfKBYv+hWAF2c3k1z/NXfVr0GX7M0LhUMJa5uHqq2JCW6eVDnMZmWBHfWZOn43fTbFJ0rxHWmNk8KGpbNGgf0k2JOMXtvMH+238LFuLOBMUoGah1jCCpv3UMudecJ2M30q68kbeB8Z9TBP2INPzT7oNw3vqcvwnrqMjA+WM6KmhB81d7DE9jCx5p/Q+k8mesqTZLqsJUUYQPjwhayf3pdXtmSRV6NFaS/nj5P7selwGU9O6kf0iRpARN9mZn9eHZkVTSTk1nb2DOygq9H2tFX4ubhZUnu/hRuvEvBaoJs0YdfdgvOjHdo/+nVer0v+mK2uwxi/9GGUYa3Ix/4eOH3dahi8gFd2a/ExjiPMs42o0hOMszoGjbDcwZox7n1xOWbNrhQZpXI909M2gasDRC5EZzCR7vsQQxGILf0IT0873mmZRXlDCznGALKrfLg14BD5NX0YOXQmeQFD8DpSwcbG8TgrZWzVO/PPej3DfHwZ/LvXeO/DX7iT3Xyni2JQqDOlfvOYn7eV2NI1vNK2gIxMHfOjDWw7XglAg97IpsNl7MqpoVit48P7olEpbPj4QAHLJvdjbqQ3OzKremToHe/JlIGe3b5GoudIAnAZ0CV/jGLP39E1N6GwkQGCpW1Yuxg4G7Tckbsb56HzwMEG0j9DsefvFLUt4Kdpz/DI+BDUWgPf/XQI173bWGUIxs6gYb58Lx/fchfNbuncJVTjbXUMjUzGWkcvHqxKZI7ZDO2Her7FPL5wfoiZ/e9Elf4ZisTX2d22ANWYxRQ2irxeFc2cSCU/JtehsXHgQ9u5TNx9CNXdy3jSdgBHj39AnL6ZH5jCShyxs/6JhzdZcU/4/YDIXHbzvPWXAHxoup+knVUkBg3m5dEv4iObyJz2NF1hnY5ANwXTBnpy10h/itWp5NVo+dfmTGKC3fhk5yE+CjtEiFxFyMhHLO/HBehYyx/Mr2NXjmVvgzSzXxySAFwGNhrHUda2gGkVDUQXfmj5oo2iMy7QUQdwMK+O2D8tQmXQoYt9Bh9hRmc3nI2pJZxY9wUPHf+JV+ctZqK8FMWev2MXfQcrjiajGPIoQwIe5r26Y6S4ldLgPIGAbGtCKxtQh/uRqrqN/RUyCpM1LB15J0dP1KLynI0GZ16rngTArwlHWXxiB4ahdnzuMoVPZ38AA0ZwNOltzJ6/EmqsZ83Jo/zD9kEyq2Yiqw6ldPeHBC28G7sxS9hbomCsADkGy+lCWwvaaLUZz4uzwztnaJ3BBIiM7+/BvzZn8o8pXpTuWsPIyX9A6eZFRPHHROd9CEWAjcN5sytdZ36wZAJigqukNf0lIAnAZWBO7FA22jxDyEAFHFMBAkQu7Owq5DhpEgfz6liuD+TDrZbiH8XUf3D/mOjOe8yP9uO7JffglOvD9LBW5IPngI2VZV9B+V7iQuMQwxwYmnScKJc0ZgbOIeuNj/FMXc+P+iE0jzLzsNVPFJfOY4OjLa/mxLA82B17gxEVjdwl24WpAqYWH8JD1cCQwZAZ8WfGB7ryx3QR1BpGZSoxpTex3PwRayb+kyEnE5l2/CccK/vjt/Rh2J8I2/9KQpuOPcwh0E3RPiNnds7MChsrXv05mw/35qNvMzOjYQN31X/E3p32xPsuJG78Q6Qa9QT3ceRH3RjmaLvvBuTqYNNtFL+7DIBEz5EE4DJw2rp14vOdX2/4am3nWQKjX/gjj6eWEDbwFjjhdlZRkauDDQ/eOhz274Ptr4KTPUQuRJX8IYsR0Xi2sDFTzX2jBgGD2Jhawu8eux+9nwsD/aP5k7gN39Qv0VpXYxi4CmjfbafR4P3TN9zlsoN9gQPwkDeQGRBAo70tn+w8REZpCOkVo1kZ5sz6aF8Gy95nhm8+C6wT+JNjBM0jjNw1ZRZgSdEdPVGLvWomyxzcO9fxXWdmjc7AB3vzUGvbCFbomdrPidSah1mWPRBNTi4ZpX3YlTOBifRhV04VLTanjgU70+ClKH7vIwnAFaTrWQLyriJxvlNwIhdaioQMOkj+sLMaLqe0hVePWyqu7QwadLtXcSLIjZOhd3N77GBcCQB1Ig75OxEOrwXbBQgVeahenMkcrYZiLxXBu4vZccdUymUy/tT8OUZPe7JchzB08nDSiGJLzSo2TzbR7DQLs91tNObW8JHPGEp+Pc771d/yg24ML+XEsGyyO6404nLoe+xkE4FTxTk7MqtQa9sI6ePAhsGZuCauwG78S8z3iOR4WQNPTupHTLBbt+78mQb/W6L4UtFPz5AE4HLTJSMgV7l1dhXq8R+og5tlbbz9rzD+WRj/HCASHhLH17qP8Uk/ga1vM32sN0Ep7C5oZqONJZCIXwzk7yazrIFXc7KJ0LxBTLgGBeCQZaDaSskAtxF8JfrT39GD/xRFoqkqYmJYH56c1A+XTMtSIC5oCGJUJLtL0kgqUDPfai9sf5fZo19kd9h49AYTZQfW4Gb9JWVteSw5fBdFal3n+v/hccEgimwwjef+8ZZDQe0P1LE/rw7j1mxigl1RKWw6g58dhUGXkraTin56hiQAl5v2smCdwcSnstvOu549J10rC9szCTa7VhD666dUH1Fy/La7yZTPY1SQKz4BC0611W4/sCTEcxrLf3yPsD2HSJ0RRErgQPoGi4je/dgk9+aYIYF/NY5Bgxw/lT27cmowGM1kVozmz57WMOA+XB1sWL0wio2pJQQHDWHvThmfFwxlV2EN/TycqAj6Hd+3OrOxZBgatY6JYX0AkZU7c5kY1qczJtAyeTZzdbZ8n14GQFKBmqQCNXqDGXsbK1IL1ezPq+t8Xy52JpeWCz1DEoDLTbvxbtSN4dWdv309q2nREF/ww2kHjqi1Bl7KG0KA30xUyj6Mf+hBCstbCY/2I7bDSNo9D43nNDb8+T3mb/0EEUipCMWlnwN/b5mExtYZpWEbdp6/MqDmKC3cx8zBwfjYaPEt/o6nGczyqkk0ZlrKbztm5A/25PFqTgwq1LzikcovBQJ7SkXSlNPR0EKgnZ43vPfQGHYXGaUWb8JgNLcbtsi/NmdSWKdDpbAmyF3BoeIGMisaSMi1GH5IH4fOSH/XlN+bd0b2WASkop+eIQnA5aa9ym+O1kCLTclvXs92d+DIxtQSfsw14Kq8C7W8DWN562n3UmsNZH/5CrGla8iq+o7VAxZRGbYPjxRvNKPcWcqXeIR68KFpNncJchrUGuJ0pSQHR5LZFsAtJ/9FcP1+VoY9SZrvfdw5UAG7XgEENIMfwKytZW2/A9iLLcSWrqGwTcse5uDuaIO9jRWT1T/ilvglJ6ub2JUziphgN965Z3jnTK7RGcivSaFIrWN+oBu39OuD3mBmoLeSzHKLEFj6AzoyP9qvM9+/MbVEMupeRhKAK8TFzkjd9RToahRdS2c73GWdwQQFamKtoUJmxxxW8U24iSf8TAQHzsdQW0ON+ySS9qqZNXkBQ0plfFVbhkdTIxR9RLD1ftLtRjJk9uMMVriRs+lfxOStBCCnVI8mu5rJ1l+iG/0MupCXyM8eiKpIwzLFAYbf/QQ/pD+ETt6fsMELWObVhM5gRKOztPH6ek86d1rtIdx5KEVqsLeWobCRs3JnNstnhvP2glNC0fG+vXln5Glfk+g9BFG88lvzo6OjxdTU1Cv+3GuZM0/AOXPde+ZauOPzu4Jacdn3Ekx7hY/TGyjbvQZV1N3w9QZcXEv5j3IBi9I3oJ3ZzL3BI6isaiW2dA0nlbFsDv4rKFyZG+lD2ebXGFf0Nm+1zUO0VvBpy1jumzwchY2c939O5qPwQ0QHuKIZ/AB//f4YfQu+RTVmMS3WKvQGI6MqP2dyybvoxr+EYuJTgKW334P/S+msBiys0/Gw1Y88b/0lr7Qt4GToEl6cPZAf0svQt5mxt5Zxf2z3zUIkfhuCIKSJohh9oeskD+By8RsPKOkaFATOChCeK2io2P0XyN+BwdDKLQ1Ggq33U/dtAt8UhhG2N4fIsdlUjr0bl+pdBGtWsa3tVvpYedOv4QCeed/wfHtVYL5pHAltNaS4zOJwnVX73QXmR/uhM5jYx3CCRwbh6mDD3xe4sTE1GJ3BxMqdJwGoCJ1AUludpclp+6uf33SUwjodAIV1OsaEuKHyWUKdVQgq03iGWiv5Ib3stEChwkbe+fNLh4FefiQBuEzo9q9GceB1dNomFNNePP/F2joWmU+dEQCWtlg6g9FyalB7pxzgNA/h1Z+zUY57jOkyM+8ZzDzWmEhRow+7i4J4deISJuYlsytkJIG2Chqax2NnbYVNawOuJQ3sChhK1bA7WB7lgc5g4sdcAxPDlvDG7IH8kF4OiDwQ6YQqfTWujOGlnVUobOQ8Mj6kczmTV9PMvpM11DS18ruxg8npF8zYgZ5d9vdbvEtvpR3zo/24Pzaw3ZBHItuTx8qfsztbgo8IdAUs5b0NOkvdgEbbysqdxcAp0ZPy+72LJACXicyyBqK7fDwv7ZuB5o9/iU9TVcyP9ussoT3T6DroEIJp0X58kVPAV0dXYmPji/vRIMZlHmK5cR1THphDzACLcT3zzRHerpnFXxr3UX1EyUmnWDSiExiMjO/vwcH8WuqaW3l+UwbPzhhASqEa22Nfwp6/ExTwB54dN5tF5u9Be3/nCb81W1dSUDwADc6s3pPLpHDPzhkd4JV5Q8/Z3vvMbb4f7MnrbPBxML+OvBotfZX2Z50XIOX3exdJAC4TIbOf4uBWe8JmLL3wxd2kCi+UJuwqCG0VA4isCeAhw35WjxzDjiZrHnn4VvLm3MHBzZlMGejJxkdj2Zhawm0h0ex7x4V3DcE0HiwCYG96DiPqt7DRNB4Nzjy1IZ3COh12k8cxKPBh0k6WcgvfoCj6EGysLBt20j8jJm8lv3e8j/80z6DNJPLqz9mMCnLt7OfXNYCnirY57zZfy1LDiM5g4v7RgRSrdTw1tf+ppqBdrjvf+yLx25AE4DKh6tOXmEX/6NnF3aQKe5w1UKuZ8+rfyPMZhrYhHR9tGXMenAdLFvOv9cntRT3HGNffki1wpQm38GasckyMCnJFLhMYVPi/Llt75xDhqyTI3YGxkeH0lfcluvBDdD7PQP9/QORC1FoDP+rGEBTwBz7KGcjYUDfaTBZ3P6lAzaRwj05j7+mM7epgg8JGzqs/ZxPSx+HsrsBcHff/Rl9ySAJwDeHqYMMj0S6QvvqCwUO11sDHOzPhk08BD34MGs/g3Xk88vCtcNdcdLtWMFQVQ1uoOwO9nU8ZoXwz44reYfWgZfSZMYcf0suw81nCL6UqNuYPBaC22cD+vDqG+pbhyjhmj36RzcJE5kRavv9/G9LZlVPDsskLeTRYjs5gZOXOXPxU9ni72DMtyBr2r4TIhRds3tmVrunNrsVAHVwN9/9GX3JIAnAZ+K2zxmnX9/DMgY17c1h5oAxCJ7Gs8nOW717H/Adnw5LFsH8lij1/Z6gpEtdxbzInNgS39kBifd1UGly3ET7+br5Pz0a/ew35Qb9j2u0vcF978G98fw9sfj2JRtvGyoNVrHeLprDOslMP6Kw/6EjZfXyggLGhbiTk1lGi0VO152eC8laiM5j4V+HYbpt3dvcedSwZOgTmX5szT6v+uxru/42+5JAE4DLQk1mjqwGcdn302R2FzzIWtZr5f1uKztofEJibtZcdy9+Ae+Z1vtaQt5fJ+TvYW/o9MLRzHHs3fMk4dQJ7d37J/EAVCusveaUAdmQG86ep/QE6A3JjQ90BSwpvbKg7OoORuZE+wOnBu5U7c3n4lmAABvZVEjZyOJxwY6NuDLtyqs7q86fWGjqN/MwS3zNFoGv139U4KvxGLymWBOAy0JNZo6vRn3a9g03nzH+qss/YGVl/ZIgKpkzB9fBh/sR+EATe+veXrKx1RHeg0GLEDm5oZ77Lls9epiC3lIIDGdw/1ZKLOO45m4TcGlSesxk3MhQdEKyPYG6XCH/HeKYM9OSH9HLs2jQMqvqRZTsHdWYl1FoDb20/gd5gYtnkUEAgIbcOaysZoiKk25hG15+9w83vrsT3zOq/S12H3+hu/KUgCcBloCezxplpsPOdbtN5fHaII0yZAocPWy4QBFizBvwiYWcuXQ9k2pCpo67WyPPWm9DJh0B7MvKu8cPY6ODeKTYtI5/Ae8M/URS9jQ46q/gAVAobi6DsXwnJ7XGDgXP4YE/eaUVAHam6jNL60wz6XD9XR3GR3mBkcriAzmDqrHfo7j38YE9etwbcU2G40d34S0ESgKvEeUWivYrwzoF3AuGW7repBfC7+882/iVLuF9rQGEjP6uZxo8GS02+YuT93T8Hi8h8lePPi9aR1OgjuJtTwvNlcjHTBnmxdITlNJ6YyIW8sruYD/cVcF+MP8sm9wPEs1J+FzqNxxLxt2LlzpNdKgCtzvl+nCuQ+FsyDNLM3z2SAFyLtAcCbQ0mkN3GD4l5rDxQCnjyCJxm/ND9H7irg02723+qDElTU8H2z9/k/cqozrX3/Gg/BuQXM64oHZ39EWAy86P92JBaQl6Nlg/35uPmEM4j4y3LkswKy1Ikv1bHZ3FDznrmmTN0x1oeTt/f/1sae57rFCBpZr90JAG4FjmjMGhZ7k6WlxQx/+iOs4z/t5CzdTV31X9EvdLAqznOna76uDv/COnuKNqf6+pgw4f3RfPX+GMM8lGeZmB/v21QZ3Xfuei6K7EjYzClvUS469Khp409z2Xo0szeC4iieMX/RUVFiRIXpq6kUnz/9ifEOntnUQRRFARRXLv2wq9rbhXf350r1jW3nvZ1dXW5mPjJX8T8oqKzvt/1Ned6/YXu38H7u3PFgGc3iyu2ZXde193Xfss9JX4bQKrYA1uUPIBrFbUa17kzeaSbNf+FONfaWNWnL/3nvdht4OzjAwWs3JmLzmDsrMgDOtOUXa/vuP+5duuddZxX181OsUHdBuy6G/ONXoV3LXBJAiAIwuvAHMAA5AGLRVGs74Vx3dyo1d1H+3vo9p9vbXzuwJkAQFpRPX+/bVDn67u7viOKf2b/vg46XPOOBp+LzN+j2PN37p/6D3DofmtU1zF3XUKcuVyQ6F1kl/j67cBgURSHAieA5Zc+pJucSzR+oHP78MbUEtRaw2nfmx/td9YOO4D7YwOZGNaHhNxadmRWdRrcmcd1d9xfYWPF/ry6zgKhrs/pMPyPDxTy6s/ZbDSOg6n/OOvsgzPH3JE6PCU6Yrdjleg9LskDEEVxW5dPDwJ3XNpwbnJ6wfg7OHPm7upOdzebdpfG25hawsqduacd191BxzUdRUodBUJdn71scijLZ4ZbehycY+bvjnOdCCxxGehJoKAn/4AfgYXn+f7DQCqQ6u/vf3kjINcjdXWiOGyYJdj3GwJ+oth9AO3Mr3UE4d7fnXvaNSu25YgrtmV3G3zrCBqqq8sv6dkSVx56GATsiWHvAI518++2Lte8AHxHe4/BC/2TsgBncAnGL4rdG/dZj+jGKDted67Xan99UxRfcrZ8vNCPIBn9NUVPBeCCSwBRFKec7/uCINwPzAYmtz9Y4rfQC25/TwpiusuZdwTzOqr5zqTjlOOuff7OxaXW20sR/6tET1TiXP+AGUAm0Oe3vE7yANq5xJn/nLftyWzcXCuKCf+1fLyU+7STW90kPrAuScytbrqYIffIi5HoOfTQA7jULMC7gBOwXRCEdEEQ3r/E+9089GLA70w6ZuONqSXdP1pr4OCmlZYjy5I/5oM9eWdlC+D82YQz6SjX3ZFZdVFjPld2QuLycqlZgNDeGshNxWU0frjwkmBjagnvHx/A6kHLyDGOO+3Isu6u7Ylrf6l1+VJZ79VBqgS80lxm44cLG1OHkfaP/h394bQjy8517YUMWzLg6xPpZKAryRUw/s5HXeGgmhTEu7bo6clAlxoDkOgpl9H4Oyrvuq7TLxQH6G2u9PMkegdpCXAluMwz/7nq9bt+7A3ON8tLe/OvTyQBuNxcAbe/O+Pr6Zr8t7ju5wsI/pYYgLRcuHaQBOBycoXW/JcSgPstBTy9NctLTTqvHSQBuFxcwYDfpfBbjLq3Iv3ScuHaQcoCXA6uE+OXuHGRsgBXC8n4Ja4jJAHoTW4w4+8uvShxYyEJQG9xHRv/uQxdyu3f+EhBwN7gOjZ+OHdUvqfBOimtd/0iCcClcp0bP3TfkPN8R5adiZTWu36RBOBSuAGMH3p2Dt/5kNJ61y+SAFwsN4jxn8nFGLO0E/D6RRKAi+EGNX6QjPlmQ8oC/FZuYOOXuPmQBOC3IBm/xA2GJAA9RTJ+iRsQSQB6wnVu/FJFn8S5kATgQlznxg9SRZ/EuZGyAOfjBjB+kPL0EudGEoBzcYMYP0ipPYlzIy0BuuMGMn4JifMhCcCZSMYvcRMhCUBXJOOXuMmQBKADyfglbkJ6RQAEQXhaEARREAT33rjfFUcy/nMi1RDc2FyyAAiC4AdMBYovfThXAcn4z4tUQ3Bj0xtpwLeAPwPf98K9riyS8V8QqYbgxuaSBEAQhLlAmSiKRwRB6KUhXSEk4+8RUg3Bjc0FBUAQhB2AVzffegF4HpjWkwcJgvAw8DCAv7//bxjiZUAyfgkJ4BIOBhEEYQiwE9C1f8kXKAdGiqJYeb7XXtWDQSTjl7gJ6OnBIBe9BBBF8Sjg0eWBhUC0KIq1F3vPy45k/BISp3Hz1AFIxi8hcRa9thlIFMXA3rpXryMZv4REt9z4HoBk/BIS5+TGFgDJ+CUkzsuNKwCS8UtIXJAbUwAk45eQ6BE3ngBIxi8h0WNuLAGQjF9C4jdx4wiAZPwSEr+ZG0MAJOOXkLgorn8BkIxfQuKiub4FQDJ+CYlL4voVAMn4JSQumetTACTjl5DoFa4/AZCMX0Ki17i+BEAyfgmJXuX6EQDJ+CUkep3rQwAk45eQuCxc+wIgGb+ExGXj2hYAyfglJC4r164ASMYvIXHZuTYFQDJ+CYkrwrUnAJLxS0hcMa4tAZCMX0LiinLtCIBk/BISV5xrQwAk45eQuCpcfQGQjF9C4qpxdQVAMn4JiavK1RMAyfglJK46V0cAjEbJ+CUkrgEuWQAEQXhSEIQcQRCOC4Lwnx696MQJyfglJK4BLul0YEEQJgK3AUNFUWwVBMGjRy/U6ztuIBm/hMRV5FI9gKXAv0VRbAUQRbG6x6+UjF9C4qojiKJ48S8WhHTge2AG0AI8LYpiyjmufRh4uP3TwcCxi35w7+MO1F7tQXThWhsPXHtjksZzfsJEUXS60EUXXAIIgrAD8OrmWy+0v14FxAAjgA2CIASL3aiKKIofAh+23zNVFMXoCz37SiGN58Jca2OSxnN+BEFI7cl1FxQAURSnnOchS4FN7QafLAiCGYsS1vR0oBISElePS40BxAOTAARB6A/YcG25QRISEufhkrIAwDpgnSAIxwADcH937n83fHiJz+1tpPFcmGttTNJ4zk+PxnNJQUAJCYnrm6u/GUhCQuKqIQmAhMRNzFUVgIsqI77MCILwtCAIoiAI7ld5HK8LgpAtCEKGIAjfCYLgcpXGMaP9d5QrCMJzV2MMXcbiJwjCLkEQstr/ZpZdzfF0IAiClSAIhwVB2Hy1xwIgCIKLIAjftP/9ZAmCMPpc1141ATijjHgQ8MbVGksHgiD4AVOB4qs9FmA7MFgUxaHACWD5lR6AIAhWwCpgJjAQWCAIwsArPY4uGIH/E0VxAJbak8ev8ng6WAZkXe1BdGElsFUUxXAggvOM7Wp6ABdfRnz5eAv4M3DVI6OiKG4TRdHY/ulBwPcqDGMkkCuKYr4oigbgKyyifVUQRbFCFMVD7f9vwvKH7XO1xgMgCIIvcCuw5mqOowNBEJyBccBaAFEUDaIo1p/r+qspAP2BWwRBSBIEYY8gCCOu4lgQBGEuUCaK4pGrOY5zsAT4+So81wco6fJ5KVfZ4DoQBCEQGAYkXeWh/BfLpGG+yuPoIBhLId769mXJGkEQHM518aXWAZyX3iojvkLjeR6Ydrme/VvHI4ri9+3XvIDF9f38So6tHaGbr11170gQBEfgW+CPoig2XsVxzAaqRVFMEwRhwtUaxxnIgeHAk6IoJgmCsBJ4DvjLuS6+bFxrZcTnGo8gCEOAIOCIIAhgcbcPCYIwUhTFyis9ni7juh+YDUy+nMJ4HkoBvy6f+wLlV2EcnQiCYI3F+D8XRXHT1RwLMAaYKwjCLMAOcBYE4TNRFBdexTGVAqWiKHZ4Rt9gEYBuuZpLgHiukTJiURSPiqLoIYpioCiKgVjexOGX0/gvhCAIM4BngbmiKOqu0jBSgH6CIAQJgmAD3A38cJXGgmBR57VAliiKK67WODoQRXG5KIq+7X8zdwO/XmXjp/1vtkQQhLD2L00GMs91/WX1AC7AxZYR3yy8C9gC29u9koOiKD56JQcgiqJREIQngF8AK2CdKIrHr+QYzmAMsAg42r4VHeB5URS3XL0hXZM8CXzeLtr5wOJzXSiVAktI3MRIlYASEjcxkgBISNzESAIgIXETIwmAhMRNjCQAEhI3MZIASEjcxEgCICFxE/P/F+eE9nOGhZkAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "## Improved Cross Entropy method self written\n",
    "## Parameter definition\n",
    "mu_R = 10; sigma_R= 1.5\n",
    "mu_S = 5; sigma_S = 2\n",
    "R_pdf = ERADist(\"Lognormal\",\"MOM\",[mu_R, sigma_R])\n",
    "S_pdf = ERADist(\"Gumbel\",\"MOM\",[mu_S,sigma_S])\n",
    "# target distribution\n",
    "f = lambda x: R_pdf.pdf(x[:,0])*S_pdf.pdf(x[:,1])\n",
    "# Performance function\n",
    "# g = lambda R,S: R-S\n",
    "g = lambda x: x[0,:]-x[1,:] # x has the size dimxN\n",
    "# Threshold \n",
    "gamma = 0\n",
    "N_iCE = 1000\n",
    "p = 0.2\n",
    "dim = 2\n",
    "max_it = 50\n",
    "CV_target = 1.5\n",
    "# distribution Nataf object or marginal distribution of the input variables in physical space\n",
    "M = [R_pdf,S_pdf]\n",
    "Rho = np.identity(dim)\n",
    "# Apply the Nataf transformation\n",
    "T_Nataf = ERANataf(M,Rho)\n",
    "print(\"\\nCE-based IS stage: \")\n",
    "G_LSF = lambda u: g(T_Nataf.U2X(u))\n",
    "# Initialization of variables and storage\n",
    "N_tot = 0 # Total number of samples\n",
    "# Definition of parameters of the random variables\n",
    "mu_init = np.zeros(dim)\n",
    "si_init = np.identity(dim)\n",
    "sigma_t = np.zeros(max_it)\n",
    "samplesU = list()\n",
    "# CE rpocedure\n",
    "mu_U = mu_init\n",
    "si_U = si_init\n",
    "# Funct\n",
    "# Iteration\n",
    "for t in range(max_it):\n",
    "    # Generate samples and save them\n",
    "    U = sp.stats.multivariate_normal.rvs(mean=mu_U,cov = si_U,size = N_iCE).reshape(-1,dim)\n",
    "    samplesU.append(U.T)\n",
    "    # Count generated samples\n",
    "    N_tot += N_iCE\n",
    "    # Evaluate the limit state funciton\n",
    "    geval = G_LSF(U.T)\n",
    "    # initialize sigma_0\n",
    "    if t==0:\n",
    "        sigma_t[t] = 10 * np.mean(geval)\n",
    "    else:\n",
    "        sigma_t[t] = sigma_new\n",
    "    # Calculating h for the likelihood ratio\n",
    "    h = sp.stats.multivariate_normal.pdf(U,mu_U,si_U)\n",
    "    phi = sp.stats.multivariate_normal.pdf(U,mean=np.zeros(dim),cov = np.identity(dim))\n",
    "    # likelihood ratio for the original CE weight\n",
    "    W = phi/h\n",
    "    # Indicator function\n",
    "    I = geval <= 0\n",
    "    # iCE weight W_t = I*W    W_t = h*/h_t  = (I*phi/PF)/(It*phi/PFt) = (I/PF)/(It/PFt) proportional to I/It = I / (phi(-G/(sigma_t))\n",
    "    W_t = I*W\n",
    "    # CV of W_t\n",
    "    delta_Wt = np.std(W_t)/np.mean(W_t)\n",
    "    if delta_Wt <= CV_target:\n",
    "        break\n",
    "    # solve the optimization problem\n",
    "    I_fun = lambda sigma: sp.stats.norm.cdf(-geval/sigma)\n",
    "    Wt_fun = lambda sigma: I_fun(sigma)*W\n",
    "    CV_Wt_fun = lambda sigma :np.std(Wt_fun(sigma))/np.mean(Wt_fun(sigma))\n",
    "    fmin = lambda sigma: abs(CV_Wt_fun(sigma)-CV_target)\n",
    "    sigma_new = sp.optimize.fminbound(fmin,0,sigma_t[t])\n",
    "    # Update W_t \n",
    "    W_t = Wt_fun(sigma_new)\n",
    "    # Parameter update: closed form update\n",
    "    mu_U = W_t @ U / sum(W_t) \n",
    "    Xtmp = U-mu_U \n",
    "    Xo = Xtmp * np.tile(np.sqrt(W_t),(dim,1)).T\n",
    "    Si_U = np.matmul(Xo.T,Xo)/np.sum(W_t)+1e-6*np.identity(dim)\n",
    "# total levels\n",
    "lv = t\n",
    "# calculation of the probability of failures\n",
    "Pr = 1 / N_iCE * sum(W[I])\n",
    "# Pr = 1 / N_iCE * sum(W_t) \n",
    "# transform the samples to the physical/original space\n",
    "samplesX = list()\n",
    "for i in range(lv):\n",
    "    samplesX.append(T_Nataf.U2X(samplesU[i]))\n",
    "# reference solution\n",
    "Q_exact = 0.0331\n",
    "# show p_f results\n",
    "print(\"\\n***Reference Pf: \", Q_exact, \" ***\")\n",
    "print(\"***CE-based IS Pf: \", Pr, \" ***\\n\")\n",
    "# Plot samples\n",
    "if dim == 2:\n",
    "    nnp = 200\n",
    "    xx = np.linspace(-6, 6, nnp)\n",
    "    [X, Y] = np.meshgrid(xx, xx)\n",
    "    xnod = np.array([X, Y])\n",
    "    Z = g(xnod)\n",
    "\n",
    "    fig, ax = plt.subplots(subplot_kw={\"aspect\": \"equal\"})\n",
    "    ax.contour(X, Y, Z, [0], colors=\"r\", linewidths=3)  # LSF\n",
    "    for sample in samplesU:\n",
    "        ax.plot(*sample, \".\", markersize=2)\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([4.96026107e+01, 2.93369516e+00, 8.13125097e-01, 4.28541384e-03,\n",
       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
       "       0.00000000e+00, 0.00000000e+00])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sigma_t"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([4.96026107e+01, 2.93369516e+00, 8.13125097e-01, 4.28541384e-03,\n",
       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
       "       0.00000000e+00, 0.00000000e+00])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sigma_t"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1000,)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "I.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1000,)"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(W*I).shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.03251787062491083"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Pr = 1 / N_iCE * sum(W_t)\n",
    "Pr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1000, 2)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "U .shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-29.73138327,  65.89539306])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "W_t.T @U"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-29.73138327,  65.89539306])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "W_t @U"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {},
   "outputs": [
    {
     "ename": "ValueError",
     "evalue": "operands could not be broadcast together with shapes (1000,2) (1000,) ",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mValueError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-82-5b8a0cf6bdd5>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmultiply\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mU\u001b[0m\u001b[1;33m-\u001b[0m\u001b[0mmu_hat\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m,\u001b[0m\u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msqrt\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mW_t\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mValueError\u001b[0m: operands could not be broadcast together with shapes (1000,2) (1000,) "
     ]
    }
   ],
   "source": [
    "np.multiply((U-mu_hat) ,np.sqrt(W_t))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1000,)"
      ]
     },
     "execution_count": 84,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.sqrt(W_t).shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Subset simulation method"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Intermediate failure threshold:  4.979822372132402\n",
      "\n",
      "Intermediate failure threshold:  0.0\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "0.030869999999999998"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "## Subset simulation method \n",
    "# Since we need to do the simulation in the standard normal space we need Nataf transformation\n",
    "# to transform the Inputs in the physical space to the mean=0, Cov = indentity matrix multivariate standard normal space\n",
    "dim = 2\n",
    "# Set up the Nataf distribution object\n",
    "mu_R = 10; sigma_R= 1.5;\n",
    "mu_S = 5; sigma_S = 2;Q_exact\n",
    "R_pdf = ERADist(\"Lognormal\",\"MOM\",[mu_R, sigma_R])\n",
    "S_pdf = ERADist(\"Gumbel\",\"MOM\",[mu_S,sigma_S])\n",
    "# distribution Nataf object or marginal distribution of the input variables in physical space\n",
    "M = [ERADist(\"Lognormal\",\"MOM\",[mu_R, sigma_R]),ERADist(\"Gumbel\",\"MOM\",[mu_S,sigma_S])]\n",
    "Rho = np.identity(dim)\n",
    "# Apply the Nataf transformation\n",
    "T_Nataf = ERANataf(M,Rho)\n",
    "# target distribution\n",
    "f = lambda x: R_pdf.pdf(x[:,0])*S_pdf.pdf(x[:,1])\n",
    "# number of samples per level\n",
    "N_SuS = 1000\n",
    "# Quantile\n",
    "p = 0.3\n",
    "# Correlation parameter for the conditional sampling M-H\n",
    "rho = 0.8\n",
    "# Generate samples at the first level ~ standard multi-normal distribution\n",
    "u_SuS = sp.stats.multivariate_normal.rvs(0,1,(N_SuS,dim)) #dimxN_SuS\n",
    "# Generate samples in the original space\n",
    "x_SuS = np.transpose(T_Nataf.U2X(np.transpose(u_SuS)))# N_SuS xdim\n",
    "# Evaluate the responses# g = lambda R,S: R-S\n",
    "#g = lambda x: x[:,0]-x[:,1] # x has the size Nxdim\n",
    "g_SuS = g(x_SuS)\n",
    "maxT = 100\n",
    "for t in range(maxT):\n",
    "    # Sort the responses\n",
    "    g_SuS_sort = np.sort(g_SuS)\n",
    "    # Estimate gamma_t\n",
    "    gamma_t = max(g_SuS_sort[int(p*N_SuS)],gamma)\n",
    "\n",
    "    #gamma_t = np.nanpercentile(g_SuS,p*100)\n",
    "    #gamma_t = max(gamma_t,gamma)\n",
    "    # Check if the final level is reached\n",
    "    if gamma_t == gamma:\n",
    "        break\n",
    "    print(\"\\nIntermediate failure threshold: \",gamma_hat[t+1])\n",
    "    # set seeds for conditional MCMC\n",
    "    I_SuS = g_SuS < gamma_t\n",
    "    u_seed = u_SuS[I_SuS,:]\n",
    "    g_seed = g_SuS[I_SuS]\n",
    "    # Number of seeds\n",
    "    N_seed = sum(I_SuS)\n",
    "    # Length of each chain\n",
    "    N_Chain = np.floor(N_SuS/N_seed)*np.ones((N_seed,1))\n",
    "    N_Chain[1:np.mod(N_SuS,N_seed)] = N_Chain[1:np.mod(N_SuS, N_seed)]+1\n",
    "    # Conditional sampling M-H algorithm\n",
    "    count = 0\n",
    "    for i in range(N_seed):\n",
    "        count = count+1\n",
    "        u_SuS[count,:] = u_seed[i,:]\n",
    "        g_SuS[count] = g_seed[i]\n",
    "        \n",
    "        for j in range(int(N_Chain[i])-1):\n",
    "            count = count+1\n",
    "            # generate candidate state\n",
    "            #Corr_z = (1-np.power(rho,2))*np.identity(dim)\n",
    "            #z = sp.stats.multivariate_normal.rvs([0,0],Corr_z,(dim,1))\n",
    "            z = sp.stats.norm.rvs(0,np.sqrt(1-np.power(rho,2)),(dim,1))\n",
    "            u_cand = rho*u_SuS[count-1,:]+np.transpose(z)\n",
    "            # candidate samples at the pyhsical space\n",
    "            x_cand = np.transpose(T_Nataf.U2X(np.transpose(u_cand)))# u: dimxN; x: Nxdim\n",
    "            # Evaluate the responses \n",
    "            g_cand = g(x_cand)\n",
    "            # accept or reject \n",
    "            if g_cand < gamma_t:\n",
    "                u_SuS[count,:] = u_cand\n",
    "                g_SuS[count] = g_cand\n",
    "            else:\n",
    "                u_SuS[count,:] = u_SuS[count-1,:]\n",
    "                g_SuS[count] = g_SuS[count-1]\n",
    "            \n",
    "# Total number of levels\n",
    "T_SuS = t+1\n",
    "# Evaluation of Pr(g_SuS<0)\n",
    "I_SuS = g_SuS < gamma\n",
    "Q_SuS = (np.power(p,(T_SuS-1)))*sum(I_SuS)/N_SuS\n",
    "Q_SuS"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "300"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "N_seed"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Intermediate failure threshold:  1.089590122580395\n"
     ]
    },
    {
     "ename": "IndexError",
     "evalue": "boolean index did not match indexed array along dimension 0; dimension is 1000 but corresponding boolean dimension is 2",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mIndexError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-33-48e0f114ff9e>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m     52\u001b[0m     \u001b[0mW\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m(\u001b[0m\u001b[0msp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstats\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmultivariate_normal\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mpdf\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mX\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mmean\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mzeros\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdim\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mcov\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0meye\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdim\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m/\u001b[0m\u001b[0mh\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     53\u001b[0m     \u001b[1;31m# Parameter update: Closed-form update\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 54\u001b[1;33m     \u001b[0mprod\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmatmul\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mW\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mI\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mX\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mI\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mIndexError\u001b[0m: boolean index did not match indexed array along dimension 0; dimension is 1000 but corresponding boolean dimension is 2"
     ]
    }
   ],
   "source": [
    "## Importance sampling method (Choose the IS density through the cross entropy method)\n",
    "# IS density using the cross entropy method\n",
    "# number of samples per level\n",
    "N_CE = 1000\n",
    "# Quantile value to select samples for parameter update\n",
    "p = 0.3\n",
    "# limit state function in physical space\n",
    "g = lambda x: x[:,0]-x[:,1] # x has the size Nxdim\n",
    "# distribution Nataf object or marginal distribution of the input variables in physical space\n",
    "M = [ERADist(\"Lognormal\",\"MOM\",[mu_R, sigma_R]),ERADist(\"Gumbel\",\"MOM\",[mu_S,sigma_S])]\n",
    "Rho = np.identity(dim)\n",
    "# Apply the Nataf transformation\n",
    "T_Nataf = ERANataf(M,Rho)\n",
    "dim = len(T_Nataf.Marginals)\n",
    "u2x = lambda u: T_Nataf.U2X(u)\n",
    "# Limist state function in standard space\n",
    "G_LSF = lambda u: g(u2x(u))\n",
    "# Initialization of variables and storage\n",
    "j = 0 # initial level\n",
    "maxT = 50 # estimated number of iterations\n",
    "N_tot = 0 # total number of samples\n",
    "# Definition of parameters of the random variables (uncorrelated standard normal)\n",
    "mu_init = np.zeros(dim)\n",
    "Si_init = np.eye(dim)\n",
    "gamma_hat = np.zeros((maxT + 1))\n",
    "samplesU = list()\n",
    "# CE procedure\n",
    "# Initial parameters\n",
    "gamma_hat[j]=1\n",
    "mu_hat = mu_init\n",
    "Si_hat = Si_init\n",
    "# Iteration\n",
    "for j in range(maxT):\n",
    "    # Generate samples and save them\n",
    "    X = sp.stats.multivariate_normal.rvs(mean = mu_hat,cov = Si_hat, size=N_CE).reshape(-1,dim)\n",
    "    samplesU.append(X.T)\n",
    "    # Count generated samples\n",
    "    N_tot +=N_CE\n",
    "    # Evaluate the limit state funtion\n",
    "    geval = G_LSF(X.T)\n",
    "    # Calculating h for the likelihood funtion\n",
    "    h = sp.stats.multivariate_normal.pdf(X,mu_hat,Si_hat)\n",
    "    # Check convergence\n",
    "    if gamma_hat[j]==0:\n",
    "        break\n",
    "    # obtaining estimator gamma\n",
    "    gamma_hat[j+1]=np.maximum(0,np.nanpercentile(geval,p*100))\n",
    "    print(\"\\nIntermediate failure threshold: \",gamma_hat[j+1])\n",
    "    # Indicator function\n",
    "    I = geval <= gamma_hat[j+1]\n",
    "    # Likelihood ratio\n",
    "    W = (sp.stats.multivariate_normal.pdf(X,mean=np.zeros((dim)),cov = np.eye(dim))/h)\n",
    "    # Parameter update: Closed-form update\n",
    "    prod = np.matmul(W[I],X[I,:])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[[[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         ...,\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         ...,\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         ...,\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         ...,\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         ...,\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]]],\n",
       "\n",
       "\n",
       "       [[[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         ...,\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         ...,\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         ...,\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         ...,\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         ...,\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]]],\n",
       "\n",
       "\n",
       "       [[[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         ...,\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         ...,\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         ...,\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         ...,\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         ...,\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]]],\n",
       "\n",
       "\n",
       "       ...,\n",
       "\n",
       "\n",
       "       [[[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         ...,\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         ...,\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         ...,\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         ...,\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         ...,\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]]],\n",
       "\n",
       "\n",
       "       [[[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         ...,\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         ...,\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         ...,\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         ...,\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         ...,\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]]],\n",
       "\n",
       "\n",
       "       [[[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         ...,\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         ...,\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         ...,\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         ...,\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         ...,\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.],\n",
       "         [1., 1., 1., 1.]]]])"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = np.ones([9,5,7,4])\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[[[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]]],\n",
       "\n",
       "\n",
       "       [[[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]]],\n",
       "\n",
       "\n",
       "       [[[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]]],\n",
       "\n",
       "\n",
       "       [[[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]]],\n",
       "\n",
       "\n",
       "       [[[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]]],\n",
       "\n",
       "\n",
       "       [[[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]]],\n",
       "\n",
       "\n",
       "       [[[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]]],\n",
       "\n",
       "\n",
       "       [[[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]]],\n",
       "\n",
       "\n",
       "       [[[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]],\n",
       "\n",
       "        [[1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.],\n",
       "         [1., 1., 1.]]]])"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c = np.ones([9,5,4,3])\n",
    "c"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(9, 5, 7, 3)"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.matmul(a,c).shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(9, 5, 7, 9, 5, 3)"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.dot(a,c).shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Itermediate failure threshold:  3.9343197675235135\n"
     ]
    },
    {
     "ename": "IndexError",
     "evalue": "too many indices for array: array is 1-dimensional, but 2 were indexed",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mIndexError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-35-9deeb389f590>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m    116\u001b[0m \u001b[1;31m# Apply the Nataf transformation\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    117\u001b[0m \u001b[0mT_Nataf\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mERANataf\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mM\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mRho\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 118\u001b[1;33m \u001b[1;33m[\u001b[0m\u001b[0mPr\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mlv\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mN_tot\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0msamplesU\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0msamplesX\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mCEIS_SG\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mN_CE\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mN_final\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mp\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mg\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mT_Nataf\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    119\u001b[0m \u001b[1;31m# show p_f results\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    120\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"\\n***Reference Pf: \"\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mQ_exact\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;34m\" ***\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32m<ipython-input-35-9deeb389f590>\u001b[0m in \u001b[0;36mCEIS_SG\u001b[1;34m(N, N_final, p, g_fun, distr)\u001b[0m\n\u001b[0;32m     69\u001b[0m         \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"\\nItermediate failure threshold: \"\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mgamma_hat\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mt\u001b[0m\u001b[1;33m+\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     70\u001b[0m         \u001b[1;31m# parameter update\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 71\u001b[1;33m         \u001b[0mprod\u001b[0m  \u001b[1;33m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmatmul\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mW\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mI\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mU\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mI\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     72\u001b[0m         \u001b[0msumm\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msum\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mW\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mI\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     73\u001b[0m         \u001b[0mmu_U\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mprod\u001b[0m\u001b[1;33m/\u001b[0m\u001b[0msumm\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mIndexError\u001b[0m: too many indices for array: array is 1-dimensional, but 2 were indexed"
     ]
    }
   ],
   "source": [
    "'''\n",
    " CE-SG function\n",
    " ------------------------------\n",
    " # Inputs: \n",
    " ## N: number of samples per level\n",
    " ## N_final: number of samples for the last step\n",
    " ## p: quantile value to select samples for paremeter update\n",
    " ## g_fun: limit state funtion, assume the input samples has the size Nxdim\n",
    " ## distr: Nataf distribution object or marginal distribution object of the input variables\n",
    " -------------------------------\n",
    " # Outputs:\n",
    " ## Pr: Probability of failure\n",
    " ## T: total number of levels\n",
    " ## N_tot : total number of samples\n",
    " ## gamma_hat: intermediate levels\n",
    " ## samplesU: the samples in the standard normal space\n",
    " ## samplesX: the samples in the standard normal space\n",
    " ## kfin: final number of Gaussians in the mixture\n",
    "'''\n",
    "\n",
    "def CEIS_SG (N,N_final,p,g_fun,distr):\n",
    "    # iniital check if there exits a Nataf object\n",
    "    if isinstance(distr,ERANataf):# use Nataf transform (dependence)\n",
    "        dim = len(distr.Marginals) # number of random variables (dimensiton)\n",
    "        u2x = lambda u: distr.U2X(u) # from u to x\n",
    "    elif isinstance(distr[0],ERADist):# use distribution information for the transformation (independence)\n",
    "        # Here we assume that all the parameters have the same distribution!!!, if not adjust accordingly\n",
    "        dim = len(distr)# number of random variables (dimension)\n",
    "        u2x = lambda u: distr[0].icdf(sp.stats.norm.cdf(u))# from u to x\n",
    "    else:\n",
    "        raise RuntimeError(\"Incorrect distribution. Please create an ERADist/Nataf object!\")\n",
    "    # LSF in the standard space\n",
    "    G_LSF = lambda u: g_fun(u2x(u))\n",
    "    #Initialization of variables and storages\n",
    "    t = 0# initial level\n",
    "    maxT = 100 # estimated number of iterations\n",
    "    N_tot = 0 # total number of samples\n",
    "    # Definition of parameters of the random variables in the standard normal space (uncorrelated standard normal )\n",
    "    mu_init = np.zeros(dim)\n",
    "    Si_init = np.identity(dim)\n",
    "    gamma_hat = np.zeros(maxT+1)\n",
    "    samplesU = list()\n",
    "    # CE Procedure\n",
    "    # Initializing parameters\n",
    "    gamma_hat[t] = 1\n",
    "    mu_U = mu_init\n",
    "    Si_U =  Si_init\n",
    "    # Iterations\n",
    "    for t in range(maxT):\n",
    "        U = sp.stats.multivariate_normal.rvs(mean=mu_U,cov=Si_U,size=N).reshape(-1,dim)# U_samples has the size Nxdim\n",
    "        samplesU.append(U)\n",
    "        # count generated samples\n",
    "        N_tot +=N\n",
    "        # Caluculating h for the likelihood ratio\n",
    "        h = sp.stats.multivariate_normal.pdf(U,mu_U,Si_U)\n",
    "        # Likelihood ratio\n",
    "        f = sp.stats.multivariate_normal.pdf(U,mean=np.zeros(dim),cov = np.identity(dim))\n",
    "        W = f/h\n",
    "        # check convergence\n",
    "        if gamma_hat[t] == 0:\n",
    "            break\n",
    "\n",
    "        # Indicator funciton\n",
    "        # Evaluate the limit state function\n",
    "        geval = G_LSF(U.T)\n",
    "        I = geval<=gamma_hat[t+1]\n",
    "        # obtaining estimator gamma\n",
    "        gamma_hat[t+1] = np.maximum(0,np.nanpercentile(geval,p*100))\n",
    "        print(\"\\nItermediate failure threshold: \",gamma_hat[t+1])\n",
    "        # parameter update\n",
    "        prod  = np.matmul(W[I],U[I,:])\n",
    "        summ = np.sum(W[I])\n",
    "        mu_U = prod/summ\n",
    "        Utmp = U[I,:]-mu_U\n",
    "        Xo = (Utmp)*np.tile(np.sqrt(W[I]),(dim,1)).T\n",
    "        Si_U = np.matmul(Xo.T,Xo)/np.sum(W[I])+1e-6*np.identity(dim)\n",
    "    # total steps\n",
    "    T = t+1\n",
    "    #gamma_hat = gamma_hat [:,T+1]\n",
    "    # generate samples according to the obtained IS density\n",
    "    U_final = sp.stats.multivariate_normal.rvs(mean=mu_U,cov=Si_U,size=N_final).reshape(-1,dim)\n",
    "    # Caluculating h for the likelihood ratio\n",
    "    h_final = sp.stats.multivariate_normal.pdf(U_final,mu_U,Si_U)\n",
    "    # Likelihood ratio\n",
    "    f_final = sp.stats.multivariate_normal.pdf(U_final,mean=np.zeros(dim),cov = np.identity(dim))\n",
    "    # Calculate the probability of failure\n",
    "    W_final = f_final/h_final\n",
    "    g_final = G_LSF(U_final)\n",
    "    I_final = g_final <= 0\n",
    "    Pr = sum(I_final*W_final)/N_final\n",
    "    k_fin = 1\n",
    "    # transform to the physical space\n",
    "    samplesX = list()\n",
    "    for i in range(T):\n",
    "        samplesX.append(u2x(samplesU[i][:,:]))\n",
    "    return Pr, T, N_tot, samplesU, samplesX\n",
    "# Inputs: \n",
    " ## N: number of samples per level\n",
    "N_CE = 1000\n",
    " ## N_final: number of samples for the last step\n",
    "N_final = 1000\n",
    " ## p: quantile value to select samples for paremeter update\n",
    "p = 0.3\n",
    " ## g_fun: limit state funtion, assume the input samples has the size Nxdim\n",
    "g = lambda x: x[0,:]-x[1:,] # x has the size Nxdim\n",
    " ## distr: Nataf distribution object or marginal distribution object of the input variables\n",
    "## Parameter definition\n",
    "mu_R = 10; sigma_R= 1.5\n",
    "mu_S = 5; sigma_S = 2\n",
    "R_pdf = ERADist(\"Lognormal\",\"MOM\",[mu_R, sigma_R])\n",
    "S_pdf = ERADist(\"Gumbel\",\"MOM\",[mu_S,sigma_S])\n",
    "dim = 2\n",
    "# distribution Nataf object or marginal distribution of the input variables in physical space\n",
    "M = [R_pdf,S_pdf]\n",
    "Rho = np.identity(dim)\n",
    "# Apply the Nataf transformation\n",
    "T_Nataf = ERANataf(M,Rho)\n",
    "[Pr,lv,N_tot,samplesU,samplesX] = CEIS_SG(N_CE,N_final,p,g,T_Nataf)\n",
    "# show p_f results\n",
    "print(\"\\n***Reference Pf: \",Q_exact,\" ***\")\n",
    "print(\"***CE-based IS Pf: \",Pr,\" ***\\n\")\n",
    "# Plot samples\n",
    "if dim == 2:\n",
    "    nnp = 200\n",
    "    xx = np.linspace(-6,6,nnp)\n",
    "    [X,Y] = np.meshgrid(xx,xx)\n",
    "    xnod = np.array([X,Y])\n",
    "    Z = g(xnod)\n",
    "    fig, ax = plt.subplots(subplot_kw = {\"aspect\": \"equal\"})\n",
    "    ax.contour(X,Y,Z,[0],colors = 'r',linewidths = 3)#LSF\n",
    "    for sample in samplesU:\n",
    "        ax.plot(*sample,\".\",markersize = 2)\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
